丑話都是說在前面:
1.瀏覽器支持查看瀏覽器支持情況
2.在開發(fā)過程中,可以通過 localhost 使用服務(wù)工作線程,但如果要在網(wǎng)站上部署服務(wù)工作線程,需要在服務(wù)器上設(shè)置 HTTPS。
Service Worker(服務(wù)工作線程)是瀏覽器在后臺獨立于網(wǎng)頁運行的腳本,它打開了通向不需要網(wǎng)頁或用戶交互的功能的大門。
基本流程:

服務(wù)工作線程相關(guān)注意事項:
- 它是一種 JavaScript 工作線程,無法直接訪問 DOM。 服務(wù)工作線程通過響應(yīng) postMessage 接口發(fā)送的消息來與其控制的頁面通信,頁面可在必要時對 DOM 執(zhí)行操作。
- 服務(wù)工作線程是一種可編程網(wǎng)絡(luò)代理,讓您能夠控制頁面所發(fā)送網(wǎng)絡(luò)請求的處理方式。
- 它在不用時會被中止,并在下次有需要時重啟,因此,您不能依賴于服務(wù)工作線程的 onfetch 和 onmessage 處理程序中的全局狀態(tài)。如果存在您需要持續(xù)保存并在重啟后加以重用的信息,服務(wù)工作線程可以訪問 IndexedDB API。
- 服務(wù)工作線程廣泛地利用了 promise,因此如果您不熟悉 promise,則應(yīng)停下閱讀此內(nèi)容,看一看 Promise 簡介。
Service Worker生命周期
service worker的生命周期完全獨立于網(wǎng)頁。
要為網(wǎng)站安裝service worker,您需要先在頁面的 JavaScript 中注冊。 注冊service worker之后瀏覽器將會在后臺啟動service worker。
在安裝過程中,您通常需要緩存某些靜態(tài)資源。如果所有文件均已成功緩存,那么service worker就安裝完畢。如果任何文件下載失敗或緩存失敗,那么安裝將會失敗,service worker就無法激活(也就是說,不會安裝)。 如果發(fā)生這種情況,不必?fù)?dān)心,它下次會再試一次。 但這意味著,如果安裝完成,您可以知道您已在緩存中獲得那些靜態(tài)資源。
安裝之后,接下來就是激活步驟,這是管理舊緩存的絕佳機會,我們將在service worker的更新部分對此詳加介紹。
激活之后,service worker將會對其作用域內(nèi)的所有頁面實施控制,不過,首次注冊service worker的頁面需要再次加載才會受其控制。service worker實施控制后,它將處于以下兩種狀態(tài)之一:service worker終止以節(jié)省內(nèi)存,或處理獲取和消息事件,從頁面發(fā)出網(wǎng)絡(luò)請求或消息后將會出現(xiàn)后一種狀態(tài)。
生命周期流程:

一個離線頁面示例代碼:
//先判斷瀏覽器是否支持
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
//判斷是否已經(jīng)注冊了service worker
if (navigator.serviceWorker.controller) {
//已注冊
} else {
//未注冊,執(zhí)行注冊方法
navigator.serviceWorker.register('sw.js', {
scope: './'
}).then(function(reg) {
//注冊完成
});
}
});
}
----sw.js-----
//Install stage sets up the offline page in the cahche and opens a new cache
self.addEventListener('install', function(event) {
var offlinePage = new Request('offline.html');
event.waitUntil(
fetch(offlinePage).then(function(response) {
return caches.open('pwabuilder-offline').then(function(cache) {
//緩存頁面
return cache.put(offlinePage, response);
});
}));
});
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request).catch(function(error) {
//網(wǎng)絡(luò)請求失敗,打開緩存頁面
return caches.open('pwabuilder-offline').then(function(cache) {
return cache.match('offline.html');
});
}));
});
//刷新緩存頁面
self.addEventListener('refreshOffline', function(response) {
return caches.open('pwabuilder-offline').then(function(cache) {
return cache.put(offlinePage, response);
});
});