更新后重新注入内容脚本

时间:2013-08-28 18:31:47

标签: google-chrome-extension

我有一个Chrome扩展程序,它会在每个打开的标签页中插入一个iframe。我在我的background.js中有一个chrome.runtime.onInstalled监听器,它手动注入所需的脚本,如下所示(这里有API的详细信息:http://developer.chrome.com/extensions/runtime.html#event-onInstalled):

background.js

  var injectIframeInAllTabs = function(){
    console.log("reinject content scripts into all tabs");
    var manifest = chrome.app.getDetails();
    chrome.windows.getAll({},function(windows){
      for( var win in windows ){
        chrome.tabs.getAllInWindow(win.id, function reloadTabs(tabs) {
          for (var i in tabs) {
            var scripts = manifest.content_scripts[0].js;
            console.log("content scripts ", scripts);
            var k = 0, s = scripts.length;
            for( ; k < s; k++ ) {
              chrome.tabs.executeScript(tabs[i].id, {
                file: scripts[k]
              });
            }

          }
        });
      }
    });
  };

首次安装扩展程序时,此工作正常。我希望在更新扩展程序时也这样做。如果我也在更新时运行相同的脚本,我没有看到注入新的iframe。不仅如此,如果我尝试在更新后向我的内容脚本发送消息,则所有消息都不会进入内容脚本。我见过其他人也在SO上遇到同样的问题(Chrome: message content-script on runtime.onInstalled)。在chrome扩展更新后删除旧内容脚本和注入新内容脚本的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

更新扩展程序后,Chrome会自动切断所有&#34; old&#34;内容脚本来自与后台页面交谈,如果旧内容脚本尝试与运行时通信,它们也会抛出异常。这对我来说是个缺失的部分。我所做的只是chrome.runtime.onInstalled中的bg.js,我称之为与问题中发布的方法相同的方法。这会注入另一个与正确的运行时对话的iframe。在某个时间点,旧的内容脚本会尝试与失败的运行时进行通信。我抓住了那个异常,只是删除了旧的内容脚本。另请注意,每个iframe都会被注入到自己的“隔离世界”中。 (这里解释了孤立世界:http://www.youtube.com/watch?v=laLudeUmXHM)因此新注入的iframe无法清除旧的延迟iframe。

希望这有助于将来的某个人!

答案 1 :(得分:2)

没有办法“删除”旧的内容脚本(除了使用window.location.reload重新加载有问题的页面,这会很糟糕)

如果您想更灵活地了解在内容脚本中执行的代码,请使用executeScript函数中的“code”参数,该参数允许您使用javascript代码传入原始字符串。如果您的内容脚本只是一个大函数(即content_script_function),它位于background.js

background.js 中的

function content_script_function(relevant_background_script_info) {
   // this function will be serialized as a string using .toString()
   // and will be called in the context of the content script page
   // do your content script stuff here...
}

function execute_script_in_content_page(info) {
  chrome.tabs.executeScript(tabid,
    {code: "(" + content_script_function.toString() + ")(" +
     JSON.stringify(info) + ");"});
}

chrome.tabs.onUpdated.addListener(
  execute_script_in_content_page.bind( { reason: 'onUpdated',
                                         otherinfo: chrome.app.getDetails() });

chrome.runtime.onInstalled.addListener(
  execute_script_in_content_page.bind( { reason: 'onInstalled',
                                         otherinfo: chrome.app.getDetails() });
)

其中relevant_background_script_info包含有关后台页面的信息,即它是哪个版本,是否存在升级事件,以及为什么要调用该函数。内容脚本页面仍然保持其所有相关状态。这样您就可以完全控制如何处理“升级”事件。