有一种方法可以允许内容脚本重的扩展在升级后继续运行,并在安装后立即起作用。
安装/升级
安装方法是简单地遍历所有窗口中的所有选项卡,并将一些脚本以编程方式注入具有匹配URL的选项卡中。
ManifestV3
manifest.json:
"background": {"service_worker": "background.js"},
"permissions": ["scripting"],
"host_permissions": ["<all_urls>"],
这些 host_permissions 应该与内容脚本的 matches 属性相同。
background.js:
chrome.runtime.onInstalled.addListener(async () => {
for (const cs of chrome.runtime.getManifest().content_scripts) {
for (const tab of await chrome.tabs.query({url: cs.matches})) {
chrome.scripting.executeScript({
target: {tabId: tab.id},
files: cs.js,
});
}
}
});
这是一个简化的示例,不处理框架。您可以使用
getAllFrames API并自行匹配URL,参见
匹配模式文档。
ManifestV2
显然,您必须在manifest.json中声明的
background page或
event page脚本中执行此操作:
"background": {
"scripts": ["background.js"]
},
background.js:
chrome.manifest = chrome.runtime.getManifest();
var injectIntoTab = function (tab) {
var scripts = chrome.manifest.content_scripts[0].js;
var i = 0, s = scripts.length;
for( ; i < s; i++ ) {
chrome.tabs.executeScript(tab.id, {
file: scripts[i]
});
}
}
chrome.windows.getAll({
populate: true
}, function (windows) {
var i = 0, w = windows.length, currentWindow;
for( ; i < w; i++ ) {
currentWindow = windows[i];
var j = 0, t = currentWindow.tabs.length, currentTab;
for( ; j < t; j++ ) {
currentTab = currentWindow.tabs[j];
if( ! currentTab.url.match(/(chrome|https):\/\//gi) ) {
injectIntoTab(currentTab);
}
}
}
});
历史趣闻
在古老的Chrome 26及更早版本中,内容脚本可以恢复与后台脚本之间的连接。这个问题已经在2013年http://crbug.com/168263得到解决。您可以在此答案的早期修订版中看到此技巧的示例。