Chrome 扩展:在内容脚本中导入 ES6 模块
P粉141035089
P粉141035089 2023-08-27 22:19:00
0
2
587
<p>在 <strong>Chrome 61</strong> 中,添加了对 JavaScript 模块的支持。现在我运行的是 Chrome 63。</p> <p>我正在尝试在 Chrome 扩展内容脚本中使用 <code>import</code>/<code>export</code> 语法来使用模块。</p> <p>在<strong><code>manifest.json</code></strong>中:</p> <pre class="brush:php;toolbar:false;">"content_scripts": [ { "js": [ "content.js" ], } ]</pre> <p>在<strong><code>my-script.js</code></strong>中(与<strong><code>content.js</code></strong>同一目录):</p> <pre class="brush:php;toolbar:false;">'use strict'; const injectFunction = () => window.alert('hello world'); export default injectFunction;</pre> <p>在<strong><code>content.js</code></strong>中:</p> <pre class="brush:php;toolbar:false;">'use strict'; import injectFunction from './my-script.js'; injectFunction();</pre> <p>我收到此错误:<strong><code>未捕获的语法错误:意外的标识符</code></strong></p> <p>如果我将导入语法更改为 <code>import {injectFunction} from './my-script.js';</code> 我收到此错误: <strong><code>Uncaught SyntaxError: Unexpected token {</code></strong>< /p> </p><p>在 Chrome 扩展中的 <strong><code>content.js</code></strong> 中使用此语法是否存在问题(因为在 HTML 中您必须使用 <code> <script type="module" src="script.js "></code> 语法),还是我做错了什么? Google 忽略对扩展的支持似乎很奇怪。</p></script> </code></p>
P粉141035089
P粉141035089

全部回复(2)
P粉739079318

使用动态import() 函数。

与使用 元素的不安全解决方法不同,此解决方法在相同的安全 JS 环境(内容脚本的隔离世界)中运行,您导入的模块仍然可以访问全局变量以及初始内容脚本的函数,包括内置的 chrome API,例如 chrome.runtime.sendMessage

content_script.js 中,它看起来像

(async () => {
  const src = chrome.runtime.getURL("your/content_main.js");
  const contentMain = await import(src);
  contentMain.main();
})();

您还需要在清单的Web 可访问资源中声明导入的脚本:

// ManifestV3

  "web_accessible_resources": [{
     "matches": ["<all_urls>"],
     "resources": ["your/content_main.js"]
   }],

// ManifestV2

  "web_accessible_resources": [
     "your/content_main.js"
  ]

了解更多详情:

希望有帮助。

P粉797004644

免责声明

首先,需要说明的是,自 2018 年 1 月起,内容脚本不支持模块。此解决方法通过将模块 script 标记嵌入到返回的页面中来避开限制到您的扩展程序。

这是一个不安全的解决方法!

网页脚本(或其他扩展)可以通过在 Object.prototype 和其他原型上使用 setter/getter、代理来利用您的代码并提取/欺骗数据函数和/或全局对象,因为 script 元素内的代码在页面的 JS 上下文中运行,而不是在默认情况下运行内容脚本的安全隔离 JS 环境中。

一个安全的解决方法是此处的另一个答案中显示的动态import()

解决方法

这是我的manifest.json

    "content_scripts": [ {
       "js": [
         "content.js"
       ]
    }],
    "web_accessible_resources": [
       "main.js",
       "my-script.js"
    ]

请注意,我在 web_accessible_resources 中有两个脚本。

这是我的content.js

    'use strict';
    
    const script = document.createElement('script');
    script.setAttribute("type", "module");
    script.setAttribute("src", chrome.extension.getURL('main.js'));
    const head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
    head.insertBefore(script, head.lastChild);

这会将 main.js 作为模块脚本插入网页中。

我的所有业务逻辑现在都在 main.js 中。

要使此方法发挥作用,main.js(以及我将导入的所有脚本)必须位于中清单中的 web_accessible_resources

用法示例:my-script.js

    'use strict';
    
    const injectFunction = () => window.alert('hello world');
    
    export {injectFunction};

main.js 中,这是导入脚本的示例:

    'use strict';
    
    import {injectFunction} from './my-script.js';
    injectFunction();

这有效!没有抛出任何错误,我很高兴。 :)

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板