<p>我需要將我的 Service Worker 在 Chrome 擴充功能中定義為持久的,因為我正在使用 webRequest API 來攔截特定請求的表單中傳遞的一些數據,但我不知道如何做到這一點。我已經嘗試了所有方法,但我的 Service Worker 不斷卸載。 </p>
<p>如何保持其加載並等待直到請求被攔截? </p>
與chrome.webRequest API 不同,chrome.webNavigation API 可以完美地工作,因為chrome.webNavigation API 可以喚醒 Service Worker,現在您可以嘗試將chrome.webRequest API API 放入chrome.webNavigation 中。
與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
連線
nativeMessaging在 Chrome 105 及更高版本中,只要透過 chrome.runtime.connectNative。如果主機進程因崩潰或使用者操作而終止,則連接埠將關閉,並且軟體將照常終止。您可以透過監聽連接埠的 onDisconnect
事件來防範它再次呼叫 chrome.runtime.connectNative。內容腳本的廣泛主機權限(例如
或
*://*/*如果您已經使用端口,例如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>關於持久性的警告
您仍然需要保存/恢復狀態(變數),因為不存在持久服務工作人員之類的東西,並且這些解決方法具有如上所述的限制,因此工作人員可以終止。您可以維護儲存中的狀態,範例。
請注意,您不應該只是為了簡化狀態/變數管理而讓您的工作執行緒持久化。這樣做只是為了恢復因重新啟動工作線程而惡化的效能,以防您的狀態重建成本非常昂貴,或者如果您掛接到本答案開頭列出的頻繁事件。