我们的Chrome扩展有内容脚本和后台脚本相互通信。当插件被更新时,后台脚本被停止,内容脚本开始得到Error: Extension context invalidated.
。在V2中,我们使用port.onDisconnect
事件(如描述的here )来清理事物。但是在V3中,此事件也会在5分钟后发送(后台服务工作人员被自动终止时)。因此,这个事件现在意味着要么是扩展卸载(清理应该完成),要么是SW生命周期事件(不需要清理,重新连接就可以了)。
因此,问题在于,如何明确地确定清理是否必要。
我试过:
chrome.management.
事件:onDisabled
等,但不幸的是,chrome.management
在我的内容中没有定义,而是在port.onDisconnected
回调中为chrome.runtime.id
定义的,以确定插件是否已卸载。但是id仍然存在于port.onDisconnected
内部的那个port.onDisconnected
中,试图再次执行chrome.runtime.connect()
并捕获异常。但也不例外!成功地创建了端口,但是它既没有接收消息,也没有在setTimeout(..., 0)
和setTimeout(..., 100)
中接收自己的onDisconnected
setTimeout(..., 100)
点3。前者也不会产生例外。后者是这样的,但它带来了一个有问题的持续时间的延迟(为什么是100?它能工作吗? CPU超载了吗?)和潜在的竞争条件,当其他插件功能可以尝试发送消息时,结果不可预测。所以我希望有一个更好的防弹解决方案。发布于 2022-05-13 17:02:12
多亏了wOxxOm's suggestions,我找到了一个目前看来可行的解决方案:每隔一段时间(<5秒)断开内容脚本中的端口,然后再重新连接。代码如下所示:
let portToBackground: chrome.runtime.Port | undefined = openPortToBackground();
function openPortToBackground(): chrome.runtime.Port {
const port = chrome.runtime.connect();
const timeout = setTimeout(() => {
console.log('reconnecting');
portToBackground = openPortToBackground();
port.disconnect();
}, 2 * 60 * 1000); // 2 minutes here, just to be sure
port.onDisconnect.addListener(() => {
clearTimeout(timeout);
if (port !== portToBackground) return;
// perform the cleanup
});
return port;
}
export function isExtensionContextInvalidated(): boolean {
return !portToBackground;
}
https://stackoverflow.com/questions/72229032
复制相似问题