使用 chrome 扩展 v3 从内容脚本注入 javascript

Jea*_*eri 7 javascript migration google-chrome-extension chrome-extension-manifest-v3

我正在将我的扩展从 V2 迁移到 V3。现在除了一件事之外一切都工作正常。在我的 V2 版本中我做了

const actualCode = '(' + function () { 'console.log("demo");' } + `)();`;
const script = document.createElement('script');
script.textContent = actualCode;
(document.head || document.documentElement).appendChild(script);
script.remove();
Run Code Online (Sandbox Code Playgroud)

请注意,这console.log("demo")是我需要注入的简化:)

我需要注入一些 javascript 才能使 chrome-extension-magic 生效。

现在,在 V3 中这不再起作用了。我在 devtools-console 中收到以下错误

content.js:23114 
    
   Refused to execute inline script because it violates the following 
   ContentSecurity Policy directive: "script-src 'self'". Either the 
   'unsafe-inline' keyword, a hash ('sha256-tN52+5...6d2I/Szq8='), or a nonce
   ('nonce-...') is required to enable inline execution.
Run Code Online (Sandbox Code Playgroud)

在迁移指南中我注意到这一部分

"content_security_policy": {
   "extension_pages": "...",
   "sandbox": "..."
}
Run Code Online (Sandbox Code Playgroud)

但那里没有太多描述,所以这对我来说很神奇。所以我希望知道的人可以帮助我解决这个问题?

ahu*_*igo 13

请参阅从扩展访问页面上下文中定义的变量和函数

由于content scripts是在“孤立的世界”环境中执行,因此我们无法在 content_script js 中执行一些特殊的dom操作。

这个例子将向您展示如何在“文档开始”之前将injected-script.js注入到网页中:

内容脚本.js

function injectScript (src) {
    const s = document.createElement('script');
    s.src = chrome.runtime.getURL(src);
    s.onload = () => s.remove();
    (document.head || document.documentElement).append(s);
}

injectScript('injected-script.js')
Run Code Online (Sandbox Code Playgroud)

清单.json(清单 V3)

"content_scripts": [
    {
        "matches": ["<all_urls>"],
        "js": ["content-script.js"],
        "run_at": "document_start" // <-- Instead of the default "document_end"
    }
],
"web_accessible_resources": [{
    "resources": ["injected-script.js"], // <-- Don't forget to add this
    "matches": ["<all_urls>"]
}]
Run Code Online (Sandbox Code Playgroud)

更新日期:2023-03-08

要支持es6模块导入,只需添加s.type = "module"

内容脚本.js

function injectScript (src) {
    const s = document.createElement('script');
    s.src = chrome.runtime.getURL(src);
    s.type = "module" // <-- Add this line for ESM module support
    s.onload = () => s.remove();
    (document.head || document.documentElement).append(s);
}

injectScript('injected-script.js')
Run Code Online (Sandbox Code Playgroud)

import然后你可以像这样使用 es6语句:

注入脚本.js

import { doStuff } from './my-other-script.js';

doStuff();
Run Code Online (Sandbox Code Playgroud)