企业级Chrome扩展如何检测自身是否曾被禁用?
我正在开发一款面向企业环境的Chrome扩展,需要检测用户是否曾禁用过它。已知可以通过chrome.management.onDisabled检测其他扩展的禁用状态,但不知道如何让扩展检测自身被禁用的情况。
试过一个通过内容脚本调用chrome.runtime的方案,但如果用户未打开任何http/https网站,该方案无法生效。
我目前用chrome.history做了一个检测方案:
chrome.history.onVisited.addListener((site) => { localStorage.lastActive = site.lastVisitTime; }); if (!localStorage.lastActive) return; chrome.history.search({text: "", maxResults: 1}, (data) => { let wasDisabled = data[0].lastVisitTime > localStorage.lastActive; console.log(wasDisabled); // if true, there was a history visit when the extension was turned off localStorage.lastActive = data[0].lastVisitTime; })
核心逻辑是持续记录扩展活跃时的用户最后浏览时间,重新启用时对比历史记录判断是否曾被禁用。但这个方案太繁琐且不稳定,用户清除浏览器历史记录就能绕过检测。
希望找到更可靠的实现方法,如果两个独立扩展是最简洁可靠的方案也可以接受。
方案一:Chrome.storage.local + 后台定时心跳(单扩展)
Chrome扩展被禁用时,后台脚本会停止运行,心跳也会中断。重新启用时,通过对比存储的心跳时间和当前时间差,判断是否存在长时间中断(即被禁用过)。
- 后台脚本设置定时心跳,每隔固定时间更新存储的心跳时间:
// background.js const HEARTBEAT_INTERVAL = 5 * 60 * 1000; // 5分钟 function updateHeartbeat() { chrome.storage.local.set({ lastHeartbeat: Date.now() }); } // 初始化心跳 updateHeartbeat(); setInterval(updateHeartbeat, HEARTBEAT_INTERVAL);
- 扩展启动时(后台脚本初始化)检查心跳时间:
// 后台脚本启动时执行 chrome.storage.local.get('lastHeartbeat', (result) => { const lastHeartbeat = result.lastHeartbeat; if (!lastHeartbeat) { // 首次安装,无历史记录 return; } const now = Date.now(); // 允许的最大时间差(比心跳间隔长,避免浏览器休眠误判) const MAX_ALLOWED_GAP = 10 * 60 * 1000; if (now - lastHeartbeat > MAX_ALLOWED_GAP) { // 心跳中断时间过长,判定曾被禁用 console.log('扩展曾被禁用'); // 执行业务逻辑,比如上报服务器 } // 更新心跳为当前时间 updateHeartbeat(); });
优势:无需依赖历史记录,用户无法通过清除历史绕过;单个扩展即可实现。
注意:设置合理的最大时间差,避免误判浏览器休眠场景。
方案二:双扩展互相监控(最可靠)
利用chrome.managementAPI让两个扩展互相监听对方状态,适用于企业环境对可靠性要求高的场景。
步骤:
- 两个扩展的
manifest.json都声明management权限:
"permissions": ["management"]
- 监控扩展监听主扩展的状态变化:
// 监控扩展 background.js const MAIN_EXTENSION_ID = "主扩展的固定ID"; // 监听主扩展被禁用事件 chrome.management.onDisabled.addListener((extensionInfo) => { if (extensionInfo.id === MAIN_EXTENSION_ID) { console.log('主扩展已被禁用'); // 上报服务器或记录日志 } }); // 监听主扩展重新启用事件 chrome.management.onEnabled.addListener((extensionInfo) => { if (extensionInfo.id === MAIN_EXTENSION_ID) { console.log('主扩展已重新启用'); // 执行对应业务逻辑 } });
同时主扩展可监控监控扩展的状态,确保其未被用户禁用:
// 主扩展 background.js const MONITOR_EXTENSION_ID = "监控扩展的固定ID"; chrome.management.get(MONITOR_EXTENSION_ID, (info) => { if (!info.enabled) { // 企业环境可强制启用监控扩展 } });
优势:完全不受用户操作(清除历史、存储)影响,企业可通过策略强制安装两个扩展,避免用户卸载监控端。
注意:打包时使用固定开发者证书,确保扩展ID不变。
方案三:Chrome.storage.sync(跨设备同步场景)
如果需要跨设备检测,可将心跳时间存储到chrome.storage.sync,原理和方案一一致,但数据同步到用户Chrome账号下,不会因清除本地存储失效。
// background.js function updateSyncHeartbeat() { chrome.storage.sync.set({ lastSyncHeartbeat: Date.now() }); } chrome.storage.sync.get('lastSyncHeartbeat', (result) => { const lastSyncHeartbeat = result.lastSyncHeartbeat; if (!lastSyncHeartbeat) return; const now = Date.now(); const MAX_ALLOWED_GAP = 10 * 60 * 1000; if (now - lastSyncHeartbeat > MAX_ALLOWED_GAP) { console.log('扩展曾被禁用'); } updateSyncHeartbeat(); }); setInterval(updateSyncHeartbeat, 5 * 60 * 1000);
内容的提问来源于stack exchange,提问作者derder56

