Persistenter Service Worker in der Chrome-Erweiterung
P粉323224129
2023-08-24 18:56:27
<p>Ich muss meinen Service Worker in einer Chrome-Erweiterung als dauerhaft definieren, weil ich die webRequest-API verwende, um einige Daten abzufangen, die im Formular für eine bestimmte Anfrage übergeben werden, aber ich weiß nicht, wie ich das machen soll. Ich habe alles versucht, aber mein Service Worker wird ständig deinstalliert. </p>
<p>Wie halte ich das Laden aufrecht und warte, bis die Anfrage abgefangen wird? </p>
与 chrome.webRequest API 不同,chrome.webNavigation API 可以完美地工作,因为 chrome.webNavigation API 可以唤醒 Service Worker,现在您可以尝试将 chrome.webRequest API API 放入 chrome.webNavigation 中。
目录
问题描述
解决方法:
• 漏洞利用
•
离屏
API•
nativeMessaging
API•
WebSocket
API•
chrome
消息 API• 专用选项卡
注意
根据定义,Service Worker (SW) 不能持久,浏览器必须在一定时间后强制终止其所有活动/请求,在 Chrome 中为 5 分钟。不活动计时器(即没有正在进行的此类活动时)甚至更短:30 秒。
Chromium 团队目前认为这种行为很好(团队偶尔放宽了某些方面,例如 Chrome 114 延长了 chrome.runtime每条消息后的端口),但这仅适用于观察不频繁事件的扩展,这些事件每天只运行几次,从而减少运行之间的浏览器内存占用(例如,带有 url 的 webRequest/webNavigation 事件> 过滤很少访问的网站)。可以重新设计这些扩展以维持状态,示例。不幸的是,这样的田园风光在很多情况下是不可持续的。
已知问题
问题 1:Chrome 106 及更早版本不会针对 webRequest 事件唤醒软件。 p>
尽管您可以尝试订阅像其他答案中所示的
chrome.webNavigation
这样的 API,但它仅对工作线程启动后发生的事件有帮助。问题 2:工作人员随机停止因事件而醒来。
解决方法可能是调用 chrome.runtime.reload()。
问题 3:Chrome 109 及更早版本无法延长新
chrome 的软件生命周期
已经运行的后台脚本中的 API 事件。这意味着当事件发生在 30 秒不活动超时的最后几毫秒内时,您的代码将无法可靠地异步运行任何内容。这意味着用户会认为您的扩展不可靠。问题 4:如果扩展程序维持远程连接或状态(变量)需要很长时间才能重建,或者您观察到如下频繁事件,则性能会比 MV2 差:
为新事件启动 SW 本质上就像打开一个新选项卡。创建环境大约需要 50 毫秒,运行整个 SW 脚本可能需要 100 毫秒(甚至 1000 毫秒,具体取决于代码量),从存储读取状态并重建/水合可能需要 1 毫秒(或 1000 毫秒,具体取决于数据的复杂性) 。即使使用几乎空的脚本,也至少需要 50 毫秒,这对于调用事件侦听器来说是相当巨大的开销,而事件侦听器只需要 1 毫秒。
SW 每天可能会重新启动数百次,因为此类事件是为了响应具有自然间隙的用户操作而生成的,例如单击一个选项卡,然后写入一些内容,在此期间,软件被终止并为新事件再次重新启动,从而消耗 CPU、磁盘、电池,通常会引入扩展反应的频繁可察觉的滞后。
通过错误利用“持久”服务工作者
Chrome 110 引入了一个错误:调用任何异步
chrome
API 都会使工作线程多运行 30 秒。该错误尚未修复。//背景.js
具有离屏 API 的“持久”服务工作人员
由凯文·奥古斯托提供。
在 Chrome 109 及更高版本中,您可以使用offscreen API 创建离屏文档并每 30 秒或更短时间从其中发送一些消息,以保持 Service Worker 运行。目前该文档的生命周期不受限制(仅音频播放受到限制,我们不使用),但将来可能会发生变化。
manifest.json
offscreen.html
offscreen.js
背景.js
连接
nativeMessaging
主机时“持久”服务工作线程在 Chrome 105 及更高版本中,只要通过 chrome.runtime.connectNative。如果主机进程由于崩溃或用户操作而终止,则端口将关闭,并且软件将照常终止。您可以通过监听端口的 onDisconnect 事件来防范它再次调用 chrome.runtime.connectNative。
WebSocket 处于活动状态时“持久”服务工作线程
Chrome 116 及更高版本:每隔 30 秒交换一次 WebSocket 消息以保持其活动状态,例如每 25 秒一次。
当可连接选项卡存在时“持久”服务工作者
缺点:
或*://*/*
),这会将大多数扩展程序放入网上商店的缓慢审核队列中.警告!如果您已连接端口,请不要使用此解决方法,请对下面的端口使用另一种解决方法。
警告!如果您使用 sendMessage,还可以实现 sendMessage 的解决方法(如下)。
manifest.json,相关部分:
后台服务工作者 bg.js:
所有其他扩展页面,例如弹出窗口或选项:
如果你也使用sendMessage
在 Chrome 99-101 中,即使不需要响应,您也需要始终在 chrome.runtime.onMessage 侦听器中调用 sendResponse()。这是MV3 中的一个错误。另外,请确保您在 5 分钟内完成此操作,否则立即调用 sendResponse 并在工作完成后通过 chrome.tabs.sendMessage(到选项卡)或 chrome.runtime.sendMessage(到弹出窗口)发送新消息完成。
如果您已经使用端口,例如chrome.runtime.connect
警告!如果您还将更多端口连接到 Service Worker,则需要在 5 分钟过去之前重新连接每个端口,例如295 秒内。这在 104 之前的 Chrome 版本中至关重要,无论有多少额外的连接端口,它都会杀死 SW。在 Chrome 104 及更高版本中,此错误已修复,但您仍然需要重新连接它们,因为它们的 5 分钟生命周期没有改变,因此最简单的解决方案是在所有版本的 Chrome 中以相同的方式重新连接:例如每 295 秒一次。
后台脚本示例:
客户端脚本示例,例如内容脚本:
“永远”,通过专用选项卡,当选项卡打开时
不使用软件,而是打开一个内部包含扩展页面的新选项卡,因此该页面将充当“可见背景页面”,即软件要做的唯一事情就是打开此选项卡。您也可以从操作弹出窗口中打开它。
它将具有与 ManifestV2 的持久后台页面相同的功能,但 a) 它是可见的,b) 无法通过
chrome.extension.getBackgroundPage
访问(可以替换为 chrome.extension.getViews)。缺点:
您可以通过向页面添加 info/logs/charts/dashboard 来让用户更容易忍受,还可以添加一个
beforeunload
侦听器以防止选项卡被意外关闭。 p>关于持久性的警告
您仍然需要保存/恢复状态(变量),因为不存在持久服务工作人员之类的东西,并且这些解决方法具有如上所述的限制,因此工作人员可以终止。您可以维护存储中的状态,示例。
请注意,您不应该仅仅为了简化状态/变量管理而让您的工作线程持久化。这样做只是为了恢复因重新启动工作线程而恶化的性能,以防您的状态重建成本非常昂贵,或者如果您挂接到本答案开头列出的频繁事件。