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 執行在不同的執行緒上。它們是非阻塞的,並且被設計為完全非同步的。因此,像同步 XHR 和 Web 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 將遵循以下生命週期:
- 下載
- 安裝
- 啟用
當用戶首次訪問受 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() 方法。一旦在 install 或 activate 事件上使用 Promise 呼叫了它,像 fetch 和 push 這樣的功能事件將一直等到 Promise 成功解析。
有關構建第一個基本示例的完整教程,請閱讀 使用 Service Workers。
使用靜態路由控制資源獲取方式
Service Worker 可能會產生不必要的效能開銷——當頁面在一段時間後首次載入時,瀏覽器必須等待 Service Worker 啟動並執行,才能知道載入什麼內容以及它應該來自快取還是網路。
如果您事先知道某些內容應該從何處獲取,您可以完全繞過 Service Worker,立即獲取資源。可以使用 InstallEvent.addRoutes() 方法來實現此用例以及更多功能。
其他用例構想
Service Worker 也旨在用於例如:
- 後臺資料同步。
- 響應來自其他源的資源請求。
- 接收昂貴計算資料的集中式更新,例如地理位置或陀螺儀,以便多個頁面可以使用一組資料。
- 用於開發目的的 CoffeeScript、less、CJS/AMD 模組等的客戶端編譯和依賴管理。
- 後臺服務的鉤子。
- 基於特定 URL 模式的自定義模板。
- 效能增強,例如預取使用者可能很快需要的資源,如相簿中的下一張照片。
- API 模擬。
未來,Service Worker 將能夠為 Web 平臺做許多其他有用的事情,使其更接近原生應用程式的可用性。有趣的是,其他規範可以並且將開始利用 Service Worker 上下文,例如:
介面
CacheCacheStorage-
代表
Cache物件的儲存。它提供了 Service Worker 可以訪問的所有命名快取的主目錄,並維護了字串名稱與相應Cache物件之間的對映。 Client-
代表 Service Worker 客戶端的作用域。Service Worker 客戶端可以是瀏覽器上下文中的一個文件,也可以是受活動 Worker 控制的
SharedWorker。 Clients-
代表一個
Client物件列表的容器;訪問當前源上活動 Service Worker 客戶端的主要方式。 ExtendableEvent-
在 Service Worker 生命週期中,擴充套件了分派到
ServiceWorkerGlobalScope的install和activate事件的生命週期。這確保了像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.caches和WorkerGlobalScope.caches-
返回與當前上下文關聯的
CacheStorage物件。 -
返回一個
ServiceWorkerContainer物件,該物件提供訪問與關聯文件的ServiceWorker物件的註冊、刪除、升級和通訊。
規範
| 規範 |
|---|
| Service Workers |