Chrome 瀏覽器插件 Manifest V3 版本新增中的 Service Worker 字段及解析

Service Worker

擴(kuò)展程序 Service Worker 是擴(kuò)展程序的核心事件處理腳本。這使得它們與 Web Service Worker 明顯不同

Extension Service WorkerWeb Service Worker 有一些共同點(diǎn)。擴(kuò)展 Service Worker 在需要時(shí)加載,并在其進(jìn)入休眠狀態(tài)時(shí)取消加載。只要擴(kuò)展程序 Service Worker 在加載后還會主動接收事件,它就會運(yùn)行,不過它可以關(guān)閉。與對應(yīng)的 Web 應(yīng)用一樣,擴(kuò)展 Service Worker 無法訪問 DOM,不過可以根據(jù)需要將其用于 offscreen

擴(kuò)展程序 Service Worker 不只是網(wǎng)絡(luò)代理(因?yàn)榻?jīng)常會提到 Web Service Worker)。除了標(biāo)準(zhǔn) Service Worker 事件之外,它們還會響應(yīng)擴(kuò)展程序事件,例如導(dǎo)航到新頁面、點(diǎn)擊通知或關(guān)閉標(biāo)簽頁。它們的注冊和更新方式也與 Web Service Worker 不同。

一、注冊 Service Worker

要注冊擴(kuò)展 Service Worker,先在 manifest.json 文件的 "background" 字段中指定它。使用 "service_worker" 字段,該字段會指定單個(gè) JavaScript 文件。

{
  "name": "Awesome Test Extension",
  "background": {
    "service_worker": "service-worker.js"
  },

}

二、導(dǎo)入腳本

將腳本導(dǎo)入 Service Worker 的方法有兩種:import 語句和 importScripts() 方法。

如需使用 import 語句,請將 "type" 字段添加到 manifest.json 文件中并指定 "module"

  "background": {
    "service_worker": "service-worker.js",
    "type": "module"
  }

然后,像往常一樣使用 import。請注意,不支持導(dǎo)入斷言。

import { tldLocales } from './locales.js';

像在 Web Service Worker 中一樣使用 importScripts()。

importScripts('locales.js');

1.1. 導(dǎo)入多個(gè) Service Worker 模塊

我們的 Service Worker 實(shí)現(xiàn)了兩項(xiàng)功能。為了提高可維護(hù)性,我們將在單獨(dú)的模塊中實(shí)現(xiàn)每項(xiàng)功能。首先,我們需要在 manifest.json 文件中將 Service Worker 聲明為一個(gè) ES module,這樣我們就可以將模塊導(dǎo)入到 Service Worker 中:

  1. manifest.json:
{
  "background": {
    "service_worker": "service-worker.js",
    "type": "module"
  },
}
  1. 創(chuàng)建 service-worker.js 文件并導(dǎo)入兩個(gè)模塊:
import './sw-omnibox.js';
import './sw-tips.js';
  1. 創(chuàng)建這些文件并為每個(gè)文件添加控制臺日志。
  • sw-omnibox.js:
console.log("sw-omnibox.js")
  • sw-tips.js:
console.log("sw-tips.js")

三、更新

要更新 Service Worker,向 Chrome 應(yīng)用商店發(fā)布新版本的擴(kuò)展程序。無法通過從服務(wù)器加載擴(kuò)展程序來解決此問題。出于安全原因,Manifest V3 不支持遠(yuǎn)程托管的代碼。

Service Worker 必須是擴(kuò)展程序軟件包的一部分。

四、Service Worker 事件

擴(kuò)展程序 Service Worker 同時(shí)支持標(biāo)準(zhǔn) Service Worker 事件和擴(kuò)展程序 API 中的許多事件。

1. 聲明擴(kuò)展程序事件

Service Worker 中的事件處理腳本需要在全局范圍內(nèi)聲明,這意味著它們應(yīng)該位于腳本的頂層,而不應(yīng)嵌套在函數(shù)內(nèi)。這樣可以確保它們在腳本初始執(zhí)行時(shí)同步注冊,從而使 Chrome 能夠在 Service Worker 啟動后立即將事件分派給它。

chrome.action.onClicked.addListener(handleActionClick);

chrome.storage.local.get(["badgeText"], ({ badgeText }) => {
  chrome.action.setBadgeText({ text: badgeText });
});

2. 常見事件

2.1. chrome.action

當(dāng)有用戶與擴(kuò)展程序的工具欄圖標(biāo)互動時(shí)觸發(fā),無論該操作是針對特定網(wǎng)頁(標(biāo)簽頁)還是整個(gè)擴(kuò)展程序。

2.2. chrome.management

提供與安裝、卸載、啟用和停用擴(kuò)展程序相關(guān)的事件。

2.3. chrome.notifications

提供與用戶與擴(kuò)展程序生成的系統(tǒng)通知互動相關(guān)的事件。

2.4. chrome.permissions

指示用戶何時(shí)授予或撤消擴(kuò)展程序權(quán)限。

2.5. chrome.runtime

提供與擴(kuò)展程序生命周期相關(guān)的事件、擴(kuò)展程序的其他部分發(fā)送的消息,以及可用擴(kuò)展程序或 Chrome 更新的通知。

2.6. chrome.storage.onChanged

每當(dāng)任何 StorageArea 對象被清除或某個(gè)鍵的值被更改或設(shè)置時(shí)觸發(fā)。請注意,每個(gè) StorageArea 實(shí)例都有自己的 onChanged 事件。

2.7. chrome.webNavigation

提供有關(guān)飛行中導(dǎo)航請求狀態(tài)的信息。

3. 過濾 Filter

要將事件限制為特定用例,或消除不必要的事件調(diào)用,請使用支持事件過濾器API。例如,假設(shè)某個(gè)擴(kuò)展程序會監(jiān)聽 tabs.onUpdated 事件,以檢測用戶何時(shí)導(dǎo)航到特定網(wǎng)站。系統(tǒng)會在每個(gè)標(biāo)簽頁上的每次導(dǎo)航時(shí)調(diào)用此事件。請改為搭配使用 webNavigation.onCompleted 和過濾條件。

const filter = {
  url: [
    {
      urlMatches: 'https://www.google.com/',
    },
  ],
};

chrome.webNavigation.onCompleted.addListener(() => {
  console.info("The user has loaded my favorite website!");
}, filter);

五、Service Worker 生命周期

1. 安裝

當(dāng)用戶從 Chrome 應(yīng)用商店安裝或更新 Service Worker,或者用戶使用 chrome://extensions 頁面加載或更新已解壓的擴(kuò)展程序時(shí),就會發(fā)生安裝。按以下順序發(fā)生三個(gè)事件。

1.1. ServiceWorkerRegistration.install

安裝期間觸發(fā)的第一個(gè)事件是 Web Service Workerinstall 事件。

1.2. chrome.runtime.onInstalled

接下來是該擴(kuò)展程序的 onInstalled 事件,當(dāng)該擴(kuò)展程序(而不是 Service Worker)首次安裝時(shí)、該擴(kuò)展程序更新到新版本以及 Chrome 更新到新版本時(shí),都會觸發(fā)該事件。使用此事件來設(shè)置狀態(tài)或一次性初始化,例如上下文菜單。

chrome.runtime.onInstalled.addListener((details) => {
  if(details.reason !== "install" && details.reason !== "update") return;
  chrome.contextMenus.create({
    "id": "sampleContextMenu",
    "title": "Sample Context Menu",
    "contexts": ["selection"]
  });
});

1.3. ServiceWorkerRegistration.active

最后,系統(tǒng)將觸發(fā) Service Workeractivate 事件。請注意,與 Web Service Worker 不同,此事件會在安裝擴(kuò)展程序后立即觸發(fā),因?yàn)闆]有與擴(kuò)展程序中的頁面重新加載相媲美的功能。

2. 插件啟動

當(dāng) user profile 啟動時(shí),會觸發(fā) chrome.runtime.onStartup 事件,但不會調(diào)用任何 Service Worker 事件。

3. 閑置和關(guān)閉

通常,Chrome 會在滿足以下條件之一時(shí)終止 Service Worker

  • 無操作 30 秒后。收到事件或調(diào)用擴(kuò)展程序 API 會重置此計(jì)時(shí)器。
  • 單個(gè)請求(例如事件或 API 調(diào)用)的處理用時(shí)超過 5 分鐘。
  • 當(dāng) fetch() 響應(yīng)的傳遞時(shí)間超過 30 秒時(shí)。

事件和對擴(kuò)展程序 API 的調(diào)用會重置這些計(jì)時(shí)器,如果 Service Worker 已休眠,傳入事件將使它們恢復(fù)。應(yīng)該將 Service Worker 設(shè)計(jì)為能夠靈活應(yīng)對意外終止。

4. 保存數(shù)據(jù)

如果 Service Worker 關(guān)閉,設(shè)置的任何全局變量都將丟失。將值保存到存儲空間,而不是使用全局變量。請注意,Web Storage API 不適用于擴(kuò)展程序 Service Worker。

4.1. chrome.storage API

一種擴(kuò)展程序 API,提供多種存儲類型;本地存儲、會話存儲、托管(網(wǎng)域)和同步存儲。此 API 用于存儲使用開發(fā)者定義的密鑰識別和檢索的 JSON 對象。當(dāng)用戶清除網(wǎng)頁緩存時(shí),此類存儲空間不會移除。

4.2. IndexedDB API

用于在客戶端存儲結(jié)構(gòu)化數(shù)據(jù)(包括文件和 blob)的低級別 API。此 API 提供了用于創(chuàng)建事務(wù)型數(shù)據(jù)存儲和檢索的原語。雖然此 API 通常對于簡單的使用場景而言過于復(fù)雜,但在此基礎(chǔ)上構(gòu)建了許多第三方存儲解決方案。

4.3. CacheStorage API

請求和響應(yīng)對象對的永久性存儲機(jī)制。此 API 專為 Web Service Worker 設(shè)計(jì),用于從端點(diǎn)檢索數(shù)據(jù)??赏ㄟ^多種方式使用此 API,具體取決于用戶是否查看最新數(shù)據(jù)及其重要性。有關(guān)詳情,請參閱離線指南。除非專門通過提取處理程序來代理網(wǎng)絡(luò)請求,否則應(yīng)使用 chrome.storage。

引用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容