Service Worker API

注意:此功能在 Web Workers 中可用。

Service Worker 本質上充當著 Web 應用程式、瀏覽器和網路(在可用時)之間的代理伺服器。它們旨在實現包括但不限於:建立有效的離線體驗、攔截網路請求,並根據網路是否可用採取相應措施、更新伺服器上的資源。它們還將允許訪問推送通知和後臺同步 API。

注意: Service Worker 是一種 Web Worker。有關 Worker 型別和用例的通用資訊,請參閱 Web Workers

Service Worker 概念與用法

Service Worker 是一個事件驅動的 Worker,它針對特定的源(origin)和路徑進行註冊。它採用 JavaScript 檔案的形式,可以控制與之關聯的網頁/站點,攔截和修改導航和資源請求,並以非常精細的方式快取資源,從而讓您完全掌控應用程式在某些情況下的行為(最明顯的就是網路不可用時)。

Service Worker 在 Worker 上下文中執行:因此,它們沒有 DOM 訪問許可權,並且與驅動您應用程式的主 JavaScript 執行在不同的執行緒上。它們是非阻塞的,並且被設計為完全非同步的。因此,像同步 XHRWeb Storage 這樣的 API 不能在 Service Worker 中使用。

Service Worker 不能動態匯入 JavaScript 模組,如果在 Service Worker 的全域性作用域中呼叫 import(),將會丟擲錯誤。使用 import 語句的靜態匯入是允許的。

Service Worker 僅在 安全上下文 中可用:這意味著它們的文件是透過 HTTPS 提供的,儘管瀏覽器也將 https:// 視為安全上下文,以方便本地開發。HTTP 連線容易受到 中間人 攻擊的惡意程式碼注入,並且允許訪問這些強大 API 的攻擊可能會造成更嚴重的後果。

注意: 在 Firefox 中,為了測試,您可以允許 Service Worker 在 HTTP(不安全)下執行;只需在 Firefox 開發者工具的選項/齒輪選單中勾選 **在工具箱開啟時,允許 Service Workers 在 HTTP 上執行** 選項。

注意: 與該領域之前的嘗試(例如 AppCache)不同,Service Worker 不會假設您試圖做什麼,然後在這些假設不完全正確時崩潰。相反,Service Worker 為您提供了更精細化的控制。

注意: Service Worker 大量使用 Promise,因為通常它們會等待響應透過,然後它們將以成功或失敗的操作進行響應。Promise 架構非常適合這一點。

註冊

Service Worker 首先使用 ServiceWorkerContainer.register() 方法進行註冊。如果成功,您的 Service Worker 將被下載到客戶端,並嘗試為使用者在其源(origin)內的所有 URL 或您指定的子集進行安裝/啟用(見下文)。

下載、安裝和啟用

此時,您的 Service Worker 將遵循以下生命週期:

  1. 下載
  2. 安裝
  3. 啟用

當用戶首次訪問受 Service Worker 控制的站點/頁面時,Service Worker 會立即下載。

之後,它會在以下情況下更新:

  • 導航到作用域內的頁面時。
  • Service Worker 觸發了一個事件,並且在過去 24 小時內沒有下載它。

當找到新檔案(與現有 Service Worker 位元組比較不同,或者這是此頁面/站點遇到的第一個 Service Worker)時,會嘗試安裝。

如果這是第一次提供 Service Worker,則會嘗試安裝,然後在成功安裝後,啟用它。

如果已有 Service Worker,則新版本會在後臺安裝,但尚未啟用——此時它被稱為“待定 Worker”(worker in waiting)。只有當不再有使用舊 Service Worker 的頁面載入時,它才會啟用。一旦沒有更多頁面需要載入,新的 Service Worker 就會啟用(成為“活動 Worker”,active worker)。啟用可以更早地使用 ServiceWorkerGlobalScope.skipWaiting() 完成,並且現有頁面可以使用 Clients.claim() 被活動 Worker 認領。

您可以監聽 install 事件;一個標準的操作是在此事件觸發時準備好您的 Service Worker 以供使用,例如,使用內建的儲存 API 建立一個快取,並將您希望離線執行應用程式所需的資源放入其中。

還有一個 activate 事件。此事件觸發的時間通常是清理舊快取和其他與 Service Worker 上一版本相關的物件的好時機。

您的 Service Worker 可以使用 FetchEvent 事件響應請求。您可以使用 FetchEvent.respondWith() 方法以任何您想要的方式修改這些請求的響應。

注意: 由於 install/activate 事件可能需要一段時間才能完成,Service Worker 規範提供了一個 waitUntil() 方法。一旦在 installactivate 事件上使用 Promise 呼叫了它,像 fetchpush 這樣的功能事件將一直等到 Promise 成功解析。

有關構建第一個基本示例的完整教程,請閱讀 使用 Service Workers

使用靜態路由控制資源獲取方式

Service Worker 可能會產生不必要的效能開銷——當頁面在一段時間後首次載入時,瀏覽器必須等待 Service Worker 啟動並執行,才能知道載入什麼內容以及它應該來自快取還是網路。

如果您事先知道某些內容應該從何處獲取,您可以完全繞過 Service Worker,立即獲取資源。可以使用 InstallEvent.addRoutes() 方法來實現此用例以及更多功能。

其他用例構想

Service Worker 也旨在用於例如:

  • 後臺資料同步。
  • 響應來自其他源的資源請求。
  • 接收昂貴計算資料的集中式更新,例如地理位置或陀螺儀,以便多個頁面可以使用一組資料。
  • 用於開發目的的 CoffeeScript、less、CJS/AMD 模組等的客戶端編譯和依賴管理。
  • 後臺服務的鉤子。
  • 基於特定 URL 模式的自定義模板。
  • 效能增強,例如預取使用者可能很快需要的資源,如相簿中的下一張照片。
  • API 模擬。

未來,Service Worker 將能夠為 Web 平臺做許多其他有用的事情,使其更接近原生應用程式的可用性。有趣的是,其他規範可以並且將開始利用 Service Worker 上下文,例如:

  • 後臺同步:即使沒有使用者訪問站點,也可以啟動 Service Worker,以便更新快取等。
  • 響應推送訊息:啟動 Service Worker 來向用戶傳送訊息,告知他們有新內容可用。
  • 響應特定時間和日期。
  • 進入地理圍欄。

介面

Cache

代表在 Service Worker 生命週期中快取的 Request / Response 物件對的儲存。

CacheStorage

代表 Cache 物件的儲存。它提供了 Service Worker 可以訪問的所有命名快取的主目錄,並維護了字串名稱與相應 Cache 物件之間的對映。

Client

代表 Service Worker 客戶端的作用域。Service Worker 客戶端可以是瀏覽器上下文中的一個文件,也可以是受活動 Worker 控制的 SharedWorker

Clients

代表一個 Client 物件列表的容器;訪問當前源上活動 Service Worker 客戶端的主要方式。

ExtendableEvent

在 Service Worker 生命週期中,擴充套件了分派到 ServiceWorkerGlobalScopeinstallactivate 事件的生命週期。這確保了像 FetchEvent 這樣的功能性事件在 Service Worker 升級資料庫模式、刪除過時快取條目等操作完成之前不會被分派。

ExtendableMessageEvent

當訊息通道在 ServiceWorkerGlobalScope 與其他上下文之間接收時,分派到 Service Worker 的 message 事件的物件——擴充套件了這些事件的生命週期。

FetchEvent

傳遞給 onfetch 處理程式的引數,FetchEvent 代表分派到 Service Worker 的 ServiceWorkerGlobalScope 的一個 fetch 操作。它包含有關請求和響應的資訊,並提供了 FetchEvent.respondWith() 方法,該方法允許我們將任意響應提供給受控制的頁面。

InstallEvent

傳遞給 install 事件處理函式引數的 InstallEvent 介面代表一個分派到 Service Worker 的 ServiceWorkerGlobalScope 的 install 操作。作為 ExtendableEvent 的子類,它確保在安裝期間不會分派像 FetchEvent 這樣的功能性事件。

提供了管理 Service Worker 資源預載入的方法。

ServiceWorker

代表一個 Service Worker。多個瀏覽上下文(例如,頁面、Worker 等)可以與同一個 ServiceWorker 物件關聯。

ServiceWorkerContainer

提供了一個代表 Service Worker 作為網路生態系統中整體單元的物件,包括註冊、登出和更新 Service Worker 的功能,以及訪問 Service Worker 及其註冊的狀態。

ServiceWorkerGlobalScope

代表 Service Worker 的全域性執行上下文。

ServiceWorkerRegistration

代表一個 Service Worker 註冊。

WindowClient

代表一個 Service Worker 客戶端的作用域,該客戶端是瀏覽器上下文中的一個文件,由活動 Worker 控制。這是 Client 物件的一種特殊型別,具有一些額外的可用方法和屬性。

其他介面的擴充套件

Window.cachesWorkerGlobalScope.caches

返回與當前上下文關聯的 CacheStorage 物件。

返回一個 ServiceWorkerContainer 物件,該物件提供訪問與關聯文件ServiceWorker 物件的註冊、刪除、升級和通訊。

規範

規範
Service Workers

另見