Chrome 扩展代码 vs 内容脚本 vs 注入脚本

IT技术 javascript google-chrome-extension scope content-script
2021-02-07 03:00:30

我试图让我的 Chrome 扩展程序在init()加载新页面时运行该功能,但我无法理解如何执行此操作。据我了解,我需要在 background.html 中执行以下操作:

  1. 使用chrome.tabs.onUpdated.addListener()来检查时,页面变更
  2. 使用chrome.tabs.executeScript运行的脚本。

这是我的代码:

//background.html
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    chrome.tabs.executeScript(null, {code:"init();"});
});

//script.js
function init() {
    alert("It works!");
}

我还想知道 init() 函数是否可以访问位于其他 JS 文件中的其他函数?

1个回答

Chrome 扩展程序中的 JavaScript 代码可以分为以下几组:

  • 扩展代码 - 对所有允许的chrome.*API 的完全访问权限
    这包括后台页面,以及所有可以通过 直接访问它的页面chrome.extension.getBackgroundPage(),例如浏览器弹出窗口

  • 内容脚本(通过清单文件或chrome.tabs.executeScript) -部分访问某些chromeAPI,完全访问页面的 DOM(而不是任何window对象,包括框架)。
    内容脚本在扩展和页面之间的范围内运行。window内容脚本的全局对象不同于页面/扩展的全局命名空间。

  • 注入脚本(通过内容脚本中的此方法) - 对页面中所有属性的完全访问权限。无法访问任何chrome.*API。
    注入的脚本表现得好像它们被页面本身包含一样,并且没有以任何方式连接到扩展。请参阅此帖子以了解有关各种注射方法的更多信息。

要将消息从注入的脚本发送到内容脚本,必须使用事件。有关示例,请参阅此答案注意:在扩展中从一个上下文传输到另一个上下文的消息会自动 (JSON) 序列化和解析


在您的情况下,chrome.tabs.onUpdated可能会在script.js评估内容脚本之前调用后台页面 ( ) 中的代码所以,你会得到一个ReferenceError,因为init不是。

此外,当您使用 时chrome.tabs.onUpdated,请确保测试页面是否已完全加载,因为该事件会触发两次:加载前和完成时:

//background.html
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if (changeInfo.status == 'complete') {
        // Execute some script when the page is fully (DOM) ready
        chrome.tabs.executeScript(null, {code:"init();"});
    }
});
@pvnarula 如果它是 CPU 密集型的,请考虑在后台页面中使用 Worker。如果有一个昂贵的一次性初始化步骤,请使用后台脚本。另一方面,如果存在标签/页面特定的代码,例如严重依赖于 DOM(并且后台页面的响应性很重要),请使用内容脚本,因为在一个标签中执行 JavaScript 不会干扰另一个标签,而把它放在后台页面可以防止扩展的后台脚本响应其他事件。
2021-03-16 03:00:30
谢谢你关于chrome.tabs.onUpdated射击两次的提示所以我想我的问题是我将如何注射init()我应该注入所有的 JavaScript 吗?init()通常在用户单击浏览器操作图标时调用,并init()触发一系列其他功能。
2021-03-26 03:00:30
@user1277607 当它必须访问任何页面的全局变量时,注入脚本。function init必须访问页面和扩展代码时,请使用内容脚本。请参阅链接的答案以了解如何注入脚本,以及有关实现必须访问页面变量的内容脚本的指南的答案
2021-03-28 03:00:30
对于chrome.tabs.executeScript, console,localStorage工作,尽管这些是全局窗口对象。但不是应用程序在 window 命名空间中定义的那些,例如window.ContextHub = window.ContextHub || {};. 是否有允许和不允许的列入白名单的集合?
2021-03-31 03:00:30
嗨@RobW,我有1个问题。在性能或处理方面,它们都有所不同。如果我必须处理一些大脚本,哪个更好的地方做背景或内容脚本?或者这两种方式都会造成一些失误?
2021-04-10 03:00:30