Tom*_*rth 48 browser-extension google-chrome-extension content-script
安装或升级我正在处理的Chrome扩展程序后,不会重新注入内容脚本(在清单中指定),因此需要页面刷新才能使扩展能够正常工作.有没有办法强制脚本再次注入?
我相信我可以通过从清单中删除它们然后处理在后台页面中注入哪些页面来以编程方式再次注入它们,但这不是一个好的解决方案.
我不想自动刷新用户的标签,因为这可能会丢失一些数据.安装或升级扩展时,Safari会自动刷新所有页面.
Tom*_*rth 31
有一种方法可以让内容脚本在扩展后继续运行,并在安装后立即使用它.
安装方法是简单地遍历所有窗口中的所有选项卡,并以编程方式将一些脚本注入到具有匹配URL的选项卡中.
显然,您必须在manifest.json中声明的后台页面或事件页面脚本中执行此操作:
"background": {
"scripts": ["background.js"]
},
Run Code Online (Sandbox Code Playgroud)
background.js:
// Add a `manifest` property to the `chrome` object.
chrome.manifest = chrome.app.getDetails();
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);
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
升级方法依赖于在禁用,卸载或升级扩展后注入内容脚本的事实.
建立端口连接时,会添加onDisconnect处理程序.这在断开连接事件后等待一秒钟,然后尝试重新连接.如果失败,则会触发另一个onDisconnect,以便再次进行该过程,直到建立连接.它并不完美,但它确实有效.
内容脚本:
var port;
// Attempt to reconnect
var reconnectToExtension = function () {
// Reset port
port = null;
// Attempt to reconnect after 1 second
setTimeout(connectToExtension, 1000 * 1);
};
// Attempt to connect
var connectToExtension = function () {
// Make the connection
port = chrome.runtime.connect({name: "my-port"});
// When extension is upgraded or disabled and renabled, the content scripts
// will still be injected, so we have to reconnect them.
// We listen for an onDisconnect event, and then wait for a second before
// trying to connect again. Becuase chrome.runtime.connect fires an onDisconnect
// event if it does not connect, an unsuccessful connection should trigger
// another attempt, 1 second later.
port.onDisconnect.addListener(reconnectToExtension);
};
// Connect for the first time
connectToExtension();
Run Code Online (Sandbox Code Playgroud)
小智 21
在不刷新页面的情况下强制注入内容脚本的唯一方法是通过编程注入.
您可以使用chrome tabs API获取所有选项卡并将代码注入其中.例如,您可以将清单版本存储在本地存储中,每次检查清单版本是否为旧版本(在后台页面中),如果是这样,您可以获取所有活动选项卡并以编程方式注入代码,或者任何其他解决方案确保扩展已更新.
使用以下命令获取所有标签:
chrome.tabs.query
并将您的代码注入所有页面
chrome.tabs.executeScript(tabId, {file: "content_script.js"});
在您的后台脚本中尝试此操作。许多旧方法现在已被弃用,因此我重构了代码。对于我的使用,我只安装单个 content_script 文件。如果需要,您可以迭代
chrome.runtime.getManifest().content_scripts
数组以获取所有 .js 文件。
chrome.runtime.onInstalled.addListener(installScript);
function installScript(details){
// console.log('Installing content script in all tabs.');
let params = {
currentWindow: true
};
chrome.tabs.query(params, function gotTabs(tabs){
let contentjsFile = chrome.runtime.getManifest().content_scripts[0].js[0];
for (let index = 0; index < tabs.length; index++) {
chrome.tabs.executeScript(tabs[index].id, {
file: contentjsFile
},
result => {
const lastErr = chrome.runtime.lastError;
if (lastErr) {
console.error('tab: ' + tabs[index].id + ' lastError: ' + JSON.stringify(lastErr));
}
})
}
});
}
Run Code Online (Sandbox Code Playgroud)