如何在Chrome扩展中的内容脚本之间重复使用代码

How do I re-use code between content scripts in a Chrome extension?

本文关键字:之间 脚本 代码 Chrome 扩展      更新时间:2023-09-26

我正在开发一个包含许多内容脚本的Chrome扩展。它们中的大多数使用相同的函数,所以我想在内容脚本之间共享这些函数;然而,我似乎不知道该怎么做。
内容脚本是沙盒的,因此不能访问同一个window对象。似乎应该有一个明显的解决方案,但我一直没能找到。

内容脚本是沙盒的,因此不能访问同一个窗口对象。

这并不完全正确:尽管内容脚本默认情况下不能与加载它们的页面的window对象交互,但它们共享相同的隐藏window对象;孤立的世界";。因此,如果将两个不同的内容脚本加载到同一页面中,那么两个内容脚本将使用相同的window

这里有一个例子,你自己试试,然后做这样的事情:

  • manifest.json:样品

     {
         "name": "My extension",
         ...
         "content_scripts": [
             {
               "matches": ["*://*/*"],
               "js": ["one.js", "two.js"]
             }
         ]
     }
    
  • 脚本one.js具有以下功能:

     function sayHello(name) {
         alert("Hello " + name + "!");
     }
    
  • 使用该函数的脚本two.js

     sayHello('John');
    

这里发生了什么

这很容易判断:

  1. 加载页面时,会注入内容脚本
  2. 首先注入one.js脚本,并定义sayHello函数
  3. 现在two.js和在one.js之后注入的任何其他内容脚本都可以使用该函数
  4. 呼叫CCD_ 12将提醒";你好,约翰"正如预期的那样

这就是为什么大多数开发人员(我也是)喜欢做这样的事情:

"content_scripts": [
    {
      "matches": ["*://*/*"]
      "js": ["jquery.min.js", "script.js"]
    }
]

因为这是一种包含jQuery并将其与内容脚本一起使用的简单方法。

显然,内容脚本将共享相同的window对象,即使它们是从具有chrome.scripting.executeScript()(MV3)或chrome.tabs.executeScript()(MV2)功能的后台页面注入的。

要回答您的问题:

您可以轻松地创建一个包含所有实用程序和最常用函数的脚本,因此您随时可以在第一个脚本之后注入的任何其他内容脚本中使用它们。

所以,基本上,做这样的事情:

"content_scripts": [
    {
      "matches": ["*://*/*"]
      "js": ["script1.js", "script2.js", "script3.js", ...]
    }
]

意思是:

  • 注射script1.js
  • script2.js被注入并继承了script1.js的名称空间
  • script3.js被注入并继承了script2.jsscript1.js的名称空间
  • 等等

澄清

当谷歌文档显示时:

内容脚本在一个称为孤立世界的特殊环境中执行。他们可以访问被注入页面的DOM,但不能访问页面创建的任何JavaScript变量或函数。它查看每个内容脚本,就好像在它运行的页面上没有其他JavaScript执行一样。反过来也是如此:在页面上运行的JavaScript无法调用任何函数或访问内容脚本定义的任何变量。

这意味着

  • 内容脚本不能与它们被注入到的页面的命名空间交互
  • 内容脚本不能与其他扩展插件在同一页面中注入的内容脚本的命名空间交互

但是

  • 它们可以与页面的DOM进行交互
  • 它们可以通过相同的扩展与在同一页面上注入的其他内容脚本的命名空间进行交互

在ManifestV3中,可以通过在content_scripts声明中指定"world": "MAIN"(Chrome 111及更高版本)或通过Chrome.scripting API(Chrome 95/102及更高版)注入/注册来将内容脚本加载到页面的window中。