我有一个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扩展更新后删除旧内容脚本和注入新内容脚本的正确方法是什么?
答案 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包含有关后台页面的信息,即它是哪个版本,是否存在升级事件,以及为什么要调用该函数。内容脚本页面仍然保持其所有相关状态。这样您就可以完全控制如何处理“升级”事件。