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

Moo*_*ood 6 javascript google-chrome google-chrome-extension chrome-extension-manifest-v3

我正在为 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>
Run Code Online (Sandbox Code Playgroud)

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
});
Run Code Online (Sandbox Code Playgroud)

我尝试过以下方法:

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

我刚刚开始研究 chrome 扩展,所以也许我错过了一些东西,或者这是不可能的。

wOx*_*xOm 11

Chrome 120+ 中的 chrome.userScripts API

要求扩展程序的每个用户在 chrome://extensions 中启用Developer mode,这可能会出现问题,因为它全局允许所有已安装扩展程序具有此危险权限。

示例: https: //stackoverflow.com/a/77579988

通过 MAIN 世界的个人解决方法

在不安全的页面上下文(主世界)中创建代码,而不是在内容脚本的默认隔离世界中。

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)');
Run Code Online (Sandbox Code Playgroud)

警告!您可以在未打包的扩展中自由使用它,但在网络商店扩展中使用它是有风险的,因为它违反了他们的政策。此外,这将被具有 strict 的网站阻止Content-Security-Policy,在这种情况下,您可以通过declarativeNetRequest API 删除此标头,但这会降低网站的安全性,并且如果您无条件这样做,也可能会被网上商店禁止,即您应该添加一个用户将显式启用的选项(默认情况下禁用)。

  • 这意味着这些网站具有严格的 CSP,您必须禁用或规避该 CSP,例如通过使用 [declarativeNetRequest](https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest 删除 `Content-Security-Policy` 标头/)。 (2认同)