Chrome扩展程序:如何注入用户提供的脚本?

6

我正在制作一个chrome扩展程序,用户可以输入脚本,然后按“运行”将其注入到当前标签页中。我正在使用MV3(清单v3)。有没有办法做到这一点?

我的代码:

HTML:

<div class="scriptrunner">
    <h1>Script Runner</h1>
    <textarea placeholder="Enter script here" id="script"></textarea>
    <button id="run">Run Script</button>
</div>

Javascript:

let button = document.getElementById("run");
button.addEventListener("click", async () => {
    let input = document.getElementById("script");
    let script = input.value;
    // this is where the script would be ran
});

我尝试了以下方法:

  • 使用 chrome.scripting.executeScript()
  • 使用 eval()
  • 使用 chrome.scripting.executeScript() 插入带有函数的脚本标签,然后运行该函数

我刚开始接触Chrome扩展程序开发,可能有些地方没想到,或者这根本不可能。

1个回答

10

在ManifestV3中尚未实现执行任意用户代码(用户脚本),并且仍然被Chrome Web商店的扩展程序政策禁止。

个人的解决方法(在用户脚本API实现之前)是在不安全的页面上下文(主要世界)中创建代码,而不是在内容脚本的默认隔离世界中。

您可以在未打包的扩展中安全使用它,但在Web商店扩展中使用它是有风险的,因为这违反了他们的政策,所以如果他们在审查您的代码期间发现的话,您的扩展甚至可能会被禁用/移除。

async function execInPage(code) {
  const [tab] = await chrome.tabs.query({currentWindow: true, active: true});
  chrome.scripting.executeScript({
    target: {tabId: tab.id},
    func: code => {
      const el = document.createElement('script');
      el.textContent = code;
      document.documentElement.appendChild(el);
      el.remove();
    },
    args: [code],
    world: 'MAIN',
    //injectImmediately: true, // Chrome 102+
  });
}

execInPage('console.log(123)');

警告! 如果网站有严格的Content-Security-Policy,可能会被阻止,此情况下您可以通过declarativeNetRequest API移除此头部。


非常感谢!然而,这个脚本只能在某些网站上运行。在一些网站上,它会抛出错误 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'。有没有什么办法可以解决这个问题? - Mood
2
这意味着这些网站有严格的 CSP,您需要禁用或规避它们,例如使用 declarativeNetRequest 删除 Content-Security-Policy 标头。 - wOxxOm
1
非常抱歉,但我该如何使用declarativeNetRequest来实现这个功能呢?需要创建一个规则集还是我漏掉了其他什么东西? - Mood
我查看了文档,并且根据文档添加了规则,但仍然不起作用。 - Mood
1
如果网站通过HTML<meta>标签添加了严格的内容安全策略,扩展程序无法移除它以禁用CSP,这可能无法正常工作。 - Vaibhav Nigam
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接