我有一个带有扩展页面的chrome扩展程序,该扩展程序通过简单的一次性请求将布尔变量传递到我的内容页面。然后,内容页面将根据从弹出页面传递的布尔变量的状态执行某些操作。直到我不小心删除了扩展程序(仍然处于开发人员模式,扩展程序已解压缩)并不得不重新加载它之前,它一直运行得很好。
这导致扩展上下文无效错误出现在弹出检查控制台中,并且网页控制台似乎验证了弹出页面和内容脚本未在通信。 chrome扩展处于活动状态的网页显示以下错误: unchecked runtime.lastError:消息端口在收到响应之前已关闭。
基于我已经看到的一些答案,似乎重新加载chrome扩展程序已使我的扩展程序其余部分“孤立”了我原来的工作内容脚本,这导致上述“未经检查的runtime.lastError:消息端口”在收到回应之前关闭。”错误在网页控制台上。
我相信我不能再次重新注入内容脚本,因为我的内容脚本具有DOM事件侦听器。有没有可能删除当前正在运行的孤立脚本的方法?还是有解决此问题的建议方法?
这是我的popup.js:
chrome.tabs.query({'active': true, 'currentWindow': true}, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, {cTabSettings: (some boolean variable)});
});
这是我的content.js:
// Listening for message from popup.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.cTabSettings === true) {
enabled = true;
} else if (request.cTabSettings === false) {
enabled = false;
}
});
// DOM listener and action
document.addEventListener('mousemove', function (e) {
// Some action
chrome.runtime.sendMessage({sender: "content", selText : "blah"}, function () {
console.log("success");
});
}, false);
我使用的是chrome开发人员模式76版。只是要改写一下,这个chrome扩展程序在我意外加载之前就可以正常工作(内容脚本与弹出窗口通信)。
答案 0 :(得分:1)
由于孤立的内容脚本仍可以接收DOM消息,因此,例如,可以通过window
将新的工作内容脚本中的一个发送到幻影的内容脚本中。收到消息后,您将注销所有侦听器(并使所有全局变量无效),这还将使您的旧脚本有资格进行自动垃圾收集。
content.js:
var orphanMessageId = chrome.runtime.id + 'orphanCheck';
window.dispatchEvent(new Event(orphanMessageId));
window.addEventListener(orphanMessageId, unregisterOrphan);
// register all listeners with named functions to preserve their object reference
chrome.runtime.onMessage.addListener(onMessage);
document.addEventListener('mousemove', onMouseMove);
// the popup script checks it to see if a usable instance of content script is running
window.running = true;
function unregisterOrphan() {
if (chrome.i18n) {
// someone tried to kick us out but we're not orphaned!
return;
}
window.removeEventListener(orphanMessageId, unregisterOrphan);
document.removeEventListener('mousemove', onMouseMove);
try {
// 'try' is needed to avoid an exception being thrown in some cases
chrome.runtime.onMessage.removeListener(onMessage);
} catch (e) {}
return true;
});
function onMessage(msg, sender, sendResponse) {
//...........
}
function onMouseMove(event) {
// DOM events still fire in the orphaned content script after the extension
// was disabled/removed and before it's re-enabled or re-installed
if (unregisterOrphan()) { return }
//...........
}
我假设popup.html加载WebExtension browser
API polyfill,因为它允许我们使用async / await语法而不是令人费解的回调地狱,从而使生活变得更加轻松。
<script src="browser-polyfill.min.js"></script>
popup.js应该确保在发送消息之前已注入内容脚本:
async function sendMessage(data) {
const [tab] = await browser.tabs.query({active: true, currentWindow: true});
if (await ensureContentScript(tab.id)) {
return await browser.tabs.sendMessage(tab.id, data);
}
}
async function ensureContentScript(tabId) {
try {
const [running] = await browser.tabs.executeScript(tabId, {
code: 'window.running === true',
});
if (!running) {
await browser.tabs.executeScript(tabId, {file: 'content.js'});
}
return true;
} catch (e) {}
}
答案 1 :(得分:0)
请检查this answer
这与删除脚本无关,而是为了避免万一出错。