P粉8072394162023-08-25 11:24:31
唯一的方法强制注入内容脚本而不刷新页面是通过编程注入。
您可以使用Chrome浏览器的标签API获取所有标签,并向它们注入代码。 例如,您可以将一个版本号存储在本地存储中,并在每次检查背景页中的版本号是否过旧时(如果是),您可以获取所有活动标签并通过编程方式注入您的代码,或者任何其他可以确保扩展程序已更新的解决方案。
使用以下代码获取所有标签:
chrome.tabs.query
并向所有页面注入您的代码
chrome.tabs.executeScript(tabId, {file: "content_script.js"});
P粉1584737802023-08-25 00:54:45
有一种方法可以在升级后使内容脚本重的扩展继续正常工作,并在安装后立即使其生效。
安装的方法是简单地遍历所有窗口中的所有标签,并在具有匹配URL的标签中以编程方式注入一些脚本。
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,参见匹配模式的文档。
显然,您必须在manifest.json中声明的background page或event page脚本中执行此操作:
"background": { "scripts": ["background.js"] },
background.js:
// Add a `manifest` property to the `chrome` object. chrome.manifest = chrome.runtime.getManifest(); var injectIntoTab = function (tab) { // You could iterate through the content scripts here 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] }); } } // Get all windows 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]; // Skip chrome:// and https:// pages if( ! currentTab.url.match(/(chrome|https):\/\//gi) ) { injectIntoTab(currentTab); } } } });
在古老的Chrome 26及更早版本中,内容脚本可以恢复与后台脚本的连接。这在2013年被修复http://crbug.com/168263。您可以在此答案的早期版本中看到此技巧的示例。