首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何检测带有Manifest v3的Chrome扩展是否已卸载

如何检测带有Manifest v3的Chrome扩展是否已卸载
EN

Stack Overflow用户
提问于 2022-05-13 11:42:58
回答 1查看 875关注 0票数 0

我们的Chrome扩展有内容脚本和后台脚本相互通信。当插件被更新时,后台脚本被停止,内容脚本开始得到Error: Extension context invalidated.。在V2中,我们使用port.onDisconnect事件(如描述的here )来清理事物。但是在V3中,此事件也会在5分钟后发送(后台服务工作人员被自动终止时)。因此,这个事件现在意味着要么是扩展卸载(清理应该完成),要么是SW生命周期事件(不需要清理,重新连接就可以了)。

因此,问题在于,如何明确地确定清理是否必要。

我试过:

  1. 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超载了吗?)和潜在的竞争条件,当其他插件功能可以尝试发送消息时,结果不可预测。所以我希望有一个更好的防弹解决方案。
EN

回答 1

Stack Overflow用户

发布于 2022-05-13 17:02:12

多亏了wOxxOm's suggestions,我找到了一个目前看来可行的解决方案:每隔一段时间(<5秒)断开内容脚本中的端口,然后再重新连接。代码如下所示:

代码语言:javascript
运行
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72229032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档