【问题标题】:Chrome extension code vs Content scripts vs Injected scriptsChrome 扩展代码 vs 内容脚本 vs 注入脚本
【发布时间】:2012-04-12 12:08:14
【问题描述】:

我试图让我的 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 文件中的其他函数?

【问题讨论】:

    标签: javascript google-chrome-extension scope content-script


    【解决方案1】:

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

    • 扩展代码 - 完全访问所有允许的 chrome.* API。
      这包括background page,以及通过chrome.extension.getBackgroundPage() 直接访问它的所有页面,例如browser pop-ups

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

    • 注入脚本(通过内容脚本中的this method)- 完全访问页面中的所有属性。 无法访问任何 chrome.* API。
      注入脚本的行为就像它们被页面本身包含一样,并且不以任何方式连接到扩展。请参阅this post 了解有关各种注射方法的更多信息。

    要从注入脚本向内容脚本发送消息,必须使用事件。有关示例,请参见 this answer。注意:在扩展中从一个上下文传输到另一个上下文的消息是自动 (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();"});
        }
    });
    

    【讨论】:

    • 感谢您提供有关chrome.tabs.onUpdated 触发两次的提示。所以我想我的问题是我将如何注入init()?我应该注入我所有的 JavaScript 吗? init() 通常在用户点击浏览器操作图标时被调用,init() 会触发一系列其他功能。
    • @user1277607 当它必须访问任何页面的全局变量时,注入脚本。当function init 必须访问页面和扩展代码时,请使用内容脚本。请参阅 linked answer 了解如何注入脚本,并参阅 this answer 了解有关实施必须访问页面变量的内容脚本的指南。
    • 嗨@RobW,我有1个问题。在性能或处理方面,它们都有所不同。如果我必须处理一些大脚本,哪个更好的地方来做背景或内容脚本?或者这两种方式都会造成一些失误?
    • @pvnarula 如果它是 CPU 密集型的,请考虑在后台页面中使用 Worker。如果有一个昂贵的一次性初始化步骤,请使用后台脚本。另一方面,如果有标签/页面特定的代码,例如严重依赖 DOM(并且后台页面的响应能力很重要),使用内容脚本,因为在一个选项卡中执行 JavaScript 不会干扰另一个选项卡,而将其放在后台页面会阻止扩展程序的后台脚本响应其他活动。
    • 对于chrome.tabs.executeScriptconsolelocalStorage 有效,尽管这些是全局窗口对象。但不是应用程序在窗口命名空间中定义的那些,例如window.ContextHub = window.ContextHub || {};。是否存在允许哪些不允许的白名单集?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    相关资源
    最近更新 更多