Kev*_*sto 8 javascript google-chrome xmlhttprequest request google-chrome-extension
我需要在我的 Chrome 扩展程序中将我的 Service Worker 定义为持久的,因为我使用 webRequest API 来拦截在表单中为特定请求传递的一些数据,但我不知道如何做到这一点。我已经尝试了所有方法,但我的 Service Worker 一直在卸载。
如何保持加载并等待请求被拦截?
wOx*_*xOm 13
在您的情况下,它可能是 ManifestV3,https ://crbug.com/1024211 中的一个错误:工作人员不会因 webRequest 事件而醒来。所以只要使用 ManifestV2 直到它被修复,因为没有持久化服务工作者这样的东西。
防止扩展的 Service Worker 卸载的解决方法:
waitUntil示例 1,硬编码超时:
self.onactivate = e => {
e.waitUntil(new Promise(resolve => setTimeout(resolve, 5 * 60e3)));
};
Run Code Online (Sandbox Code Playgroud)
示例 2,等待承诺:
let allDone;
self.onactivate = e => e.waitUntil(new Promise(r => { allDone = r; })));
//................
chrome.some.event.addListener(() => {
foo().bar().finally(allDone);
});
Run Code Online (Sandbox Code Playgroud)
从任何选项卡的内容脚本或从扩展程序的另一个页面(如弹出页面)打开运行时端口。此端口将持续五分钟(服务工作者的固有限制),因此您必须使用计时器和端口的 onDisconnect 事件再次与某个随机选项卡重新连接。
缺点:
<all_urls>或*://*/*),将大多数扩展放入网上商店的慢速审查队列。实现示例:
manifest.json,相关部分:
"permissions": ["scripting"],
"host_permissions": ["<all_urls>"],
"background": {"service_worker": "bg.js"}
Run Code Online (Sandbox Code Playgroud)
后台服务工作者 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();
}
}
Run Code Online (Sandbox Code Playgroud)
打开一个带有扩展页面的新标签页,例如chrome.tabs.create({url: 'bg.html'}).
它将具有与 ManifestV2 的持久背景页面相同的功能,但是 a) 它是可见的,并且 b) 无法通过chrome.extension.getBackgroundPage(可以用chrome.extension.getViews替换)访问。
缺点:
您可以通过向页面添加信息/日志/图表/仪表板来让您的用户更容易忍受,还可以添加一个beforeunload侦听器以防止选项卡被意外关闭。
让我们希望 Chromium 将提供一个 API 来控制这种行为,而无需诉诸此类肮脏的黑客和可悲的解决方法。同时,在crbug.com/1152255 中描述您的用例(如果尚未在那里进行描述)以帮助 Chromium 团队意识到这一既定事实,即许多扩展可能需要在任意时间段内使用持久性后台脚本,并且至少有一个这样的扩展程序可能由大多数扩展程序用户安装。
小智 10
与chrome.webRequest API不同, chrome.webNavigation API工作得很好,因为chrome.webNavigation API可以唤醒Service Worker,现在您可以尝试将chrome.webRequest API api 放入chrome.webNavigation中。
chrome.webNavigation.onBeforeNavigate.addListener(function(){
chrome.webRequest.onResponseStarted.addListener(function(details){
//.............
//.............
},{urls: ["*://domain/*"],types: ["main_frame"]});
},{
url: [{hostContains:"domain"}]
});
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,您可以通过警报唤醒服务人员(background.js)。看下面的例子:
"permissions": [
"alarms"
],
Run Code Online (Sandbox Code Playgroud)
chrome.alarms.create({ periodInMinutes: 4.9 })
chrome.alarms.onAlarm.addListener(() => {
console.log('log for debug')
});
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不是我的问题,也许你也有不同的问题。当我刷新开发扩展或停止并运行产品扩展时,有时服务工作人员会完全死亡。当我关闭并打开浏览器时,工作人员不会运行,工作人员内部的任何侦听器也不会运行它。它尝试手动注册工人。例如:
// override.html
<!DOCTYPE html>
<html lang="en">
<head>...<head>
<body>
...
<script defer src="override.js"></script>
<body>
<html>
Run Code Online (Sandbox Code Playgroud)
// override.js - this code is running in new tab page
navigator.serviceWorker.getRegistrations().then((res) => {
for (let worker of res) {
console.log(worker)
if (worker.active.scriptURL.includes('background.js')) {
return
}
}
navigator.serviceWorker
.register(chrome.runtime.getURL('background.js'))
.then((registration) => {
console.log('Service worker success:', registration)
}).catch((error) => {
console.log('Error service:', error)
})
})
Run Code Online (Sandbox Code Playgroud)
这个解决方案部分帮助了我,但这并不重要,因为我必须在不同的选项卡上注册工作人员。可能有人知道决定。我会很高兴。
| 归档时间: |
|
| 查看次数: |
1552 次 |
| 最近记录: |