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

Javascript 如何在Chrome扩展中的内容脚本之间重复使用代码?,javascript,google-chrome-extension,Javascript,Google Chrome Extension,我正在开发一个包含许多内容脚本的Chrome扩展。它们中的大多数使用相同的函数,所以我想在内容脚本之间共享这些函数;然而,我似乎不知道怎么做。 内容脚本是沙盒,因此无法访问相同的窗口对象。似乎应该有一个显而易见的解决方案,但我一直没有找到。事实并非如此:内容脚本无法与加载它们的页面的窗口对象交互,但是它们共享相同的隐藏窗口对象。因此,如果您将两个不同的内容脚本加载到同一页面中,则两个内容脚本将使用相同的隐藏窗口 下面是一个示例,请自己尝试,并执行以下操作: "content_scripts":

我正在开发一个包含许多内容脚本的Chrome扩展。它们中的大多数使用相同的函数,所以我想在内容脚本之间共享这些函数;然而,我似乎不知道怎么做。

内容脚本是沙盒,因此无法访问相同的
窗口
对象。似乎应该有一个显而易见的解决方案,但我一直没有找到。

事实并非如此:内容脚本无法与加载它们的页面的
窗口
对象交互,但是它们共享相同的隐藏
窗口
对象。
因此,如果您将两个不同的内容脚本加载到同一页面中,则两个内容脚本将使用相同的隐藏
窗口

下面是一个示例,请自己尝试,并执行以下操作:

"content_scripts": [
    {
      "matches": ["*://*/*"]
      "js": ["jquery.min.js", "script.js"]
    }
]
"content_scripts": [
    {
      "matches": ["*://*/*"]
      "js": ["script1.js", "script2.js", "script3.js", ...]
    }
]
  • manifest.json的示例:

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

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

    function sayHello(name) {
        alert("Hello " + name + "!");
    }
    
    sayHello('John');
    
这里发生了什么? 这很容易说:

  • 加载页面时,将注入内容脚本
  • 首先注入
    one.js
    脚本并定义
    sayHello
    函数
  • 现在
    two.js
    和在
    one.js
    之后插入的任何其他内容脚本都可以使用该功能
  • 呼叫
    sayHello('John')将按预期提示“Hello John!”
  • 这就是为什么大多数开发人员(我也是)喜欢做这样的事情:

    "content_scripts": [
        {
          "matches": ["*://*/*"]
          "js": ["jquery.min.js", "script.js"]
        }
    ]
    
    "content_scripts": [
        {
          "matches": ["*://*/*"]
          "js": ["script1.js", "script2.js", "script3.js", ...]
        }
    ]
    
    因为这是包含jQuery并将其用于内容脚本的简单方法

    显然,内容脚本将共享相同的
    窗口
    对象,即使它们是使用
    chrome.tabs.executeScript()
    函数从后台页面注入的

    回答你的问题: 您可以轻松创建一个包含所有实用程序和最常用函数的脚本,这样您就可以随时准备在第一个脚本之后注入的任何其他内容脚本中使用它们

    所以,基本上,这样做:

    "content_scripts": [
        {
          "matches": ["*://*/*"]
          "js": ["jquery.min.js", "script.js"]
        }
    ]
    
    "content_scripts": [
        {
          "matches": ["*://*/*"]
          "js": ["script1.js", "script2.js", "script3.js", ...]
        }
    ]
    
    意味着:

    • 注入了
      script1.js
    • script2.js
      被注入并继承
      script1.js
    • script3.js
      被注入并继承
      script2.js
      script1.js
    • 等等
    澄清 当谷歌文档显示

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

    这意味着

    • 内容脚本无法与所注入页面的命名空间交互
    • 内容脚本无法与另一扩展注入同一页面的内容脚本命名空间交互
    但是

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

    他们都在同一个孤立的世界里。他们可以很好地相互交流。您在实现这一点上遇到过困难吗?From:“孤立世界允许每个内容脚本对其JavaScript环境进行更改,而不必担心与页面或其他内容脚本冲突。”这意味着内容脚本不共享一个孤立的世界。这与我自己的发现是一致的,但我宁愿错!@Protectorone可能重复,仅适用于来自不同扩展的内容脚本。如果您从一个扩展中注入多个脚本,它们将共享上下文。澄清一下:文档的意思是“来自不同扩展的内容脚本是独立的”。谢谢,我会将其添加到应答器中。这对我来说并不适用。我可以看到两个脚本都以正确的顺序被注入和执行,但是当第二个脚本调用第一个脚本中定义的方法时,我得到了一个methodnotdefined错误。