我需要在我的 Chrome 扩展程序中将我的 Service Worker 定义为持久的,因为我使用 webRequest API 来拦截在表单中为特定请求传递的一些数据,但我不知道如何做到这一点。我已经尝试了所有方法,但我的 Service Worker 一直在卸载。
如何保持加载并等待请求被拦截?
最佳答案
在你的情况下,它可能是 ManifestV3 中的一个错误,https://crbug.com/1024211 :工作人员不会因 webRequest 事件而醒来。所以只要使用 ManifestV2 直到它被修复,因为没有持久化服务 worker 这样的东西。
防止扩展的 Service Worker 卸载的解决方法:
0. 精简版:通过 waitUntil
最多五分钟
self.onactivate = e => {
e.waitUntil(new Promise(resolve => setTimeout(resolve, 5 * 60e3)));
};
let allDone;
self.onactivate = e => e.waitUntil(new Promise(r => { allDone = r; })));
//................
chrome.some.event.addListener(() => {
foo().bar().finally(allDone);
});
1. 通过运行时端口永远保持事件状态
开一个 runtime来自任何选项卡的端口 content script或来自扩展程序的另一个页面,如弹出页面。此端口将持续五分钟(服务 worker 的固有限制),因此您必须使用计时器和端口的 onDisconnect 事件再次与某个随机选项卡重新连接。
缺点:
<all_urls>
或 *://*/*
),将大多数扩展放入网上商店的慢速审查队列。 实现示例:
"permissions": ["scripting"],
"host_permissions": ["<all_urls>"],
"background": {"service_worker": "bg.js"}
let lifeline;
keepAlive();
chrome.runtime.onConnect.addListener(port => {
if (port.name === 'keepAlive') {
lifeline = port;
setTimeout(keepAliveForced, 295e3); // 5 minutes minus 5 seconds
port.onDisconnect.addListener(keepAliveForced);
}
});
function keepAliveForced() {
lifeline?.disconnect();
lifeline = null;
keepAlive();
}
async function keepAlive() {
if (lifeline) return;
for (const tab of await chrome.tabs.query({ url: '*://*/*' })) {
try {
await chrome.scripting.executeScript({
target: { tabId: tab.id },
function: () => chrome.runtime.connect({ name: 'keepAlive' }),
// `function` will become `func` in Chrome 93+
});
chrome.tabs.onUpdated.removeListener(retryOnTabUpdate);
return;
} catch (e) {}
}
chrome.tabs.onUpdated.addListener(retryOnTabUpdate);
}
async function retryOnTabUpdate(tabId, info, tab) {
if (info.url && /^(file|https?):/.test(info.url)) {
keepAlive();
}
}
2. 替代方法:专用选项卡
打开一个带有扩展页面的新标签页,例如
chrome.tabs.create({url: 'bg.html'})
.它将具有与 ManifestV2 的持久背景页面相同的功能,但是 a) 它是可见的并且 b) 无法通过
chrome.extension.getBackgroundPage
访问(可以用 chrome.extension.getViews 替换)。缺点:
您可以通过向页面添加信息/日志/图表/仪表板并添加
beforeunload
来让您的用户更容易忍受。监听器以防止选项卡被意外关闭。ManifestV3 的 future
让我们希望 Chromium 能够提供一个 API 来控制这种行为,而无需求助于这种肮脏的黑客和可悲的解决方法。同时在 crbug.com/1152255 中描述您的用例如果尚未在此处进行描述,以帮助 Chromium 团队了解一个既定事实,即许多扩展可能需要在任意时间段内使用持久性后台脚本,并且大多数扩展用户可能至少安装了一个此类扩展。
关于javascript - Chrome 扩展中的持久服务 worker ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66618136/