ServiceWorker 是 PWA 技術棧中的一個重要成員,它是一個用於使Web 應用在離線狀態下依然可以工作,且具有網絡攔截的瀏覽器功能。這個功能由一段運行在瀏覽器後台線程的 JavaScript 代碼來實現。
一、ServiceWorker的作用
ServiceWorker 的主要功能是使得 Web 應用程序可以離線運行。通過 ServiceWorker 可以緩存 Web 應用在用戶設備上的一些文件,如HTML、JS、CSS、圖片等,這樣即使用戶離線,也能通過ServiceWorker的緩存功能加載並渲染對應的 Web 應用頁面。
另外,ServiceWorker 還能夠通過網絡攔截功能對接口的請求做一些處理,這可以用於 Offline First 等場景的開發。例如當Web 應用在用戶設備上沒有網絡或者網絡差的情況下,ServiceWorker 可以使用它的緩存功能提供一些基礎信息或者降級處理。當然,ServiceWorker 的功能不止這些,還可以配合 Push Notification 等技術進行 Web 應用的推送、更新等操作。
二、ServiceWorker無效的原因
ServiceWorker 運行的環境比較獨特,它沒有 window 或 document 的對象,也沒有 localStorage 或者 indexedDB 之類的瀏覽器 API。這樣導致ServiceWorker中某些操作是不能進行的。
另外,由於 ServiceWorker 運行在後台線程之中,所以為了確保不會出現異常情況,ServiceWorker 只能響應HTTPS或者本地環境,這也是 ServiceWorker 無法應用到經典的 HTTP 協議中的一個原因。
三、阮一峰關於ServiceWorker的看法
阮一峰在他的博客中提到過 ServiceWorker:“ServiceWorker 與 Web Worker 非常相似,都是運行在瀏覽器後台的 JavaScript 線程。ServiceWorker 和傳統瀏覽器 js 不同,它可以脫離標籤頁運行,具有比較高的獨立性,因此可以進行一些操作,比如緩存、推送等。”
在他的看來,ServiceWorker是一種比較快捷、簡便的技術,可以極大地提升Web應用的易用性和性能體驗。
四、ServiceWorker攔截請求
ServiceWorker 提供了一個對請求的攔截功能,在 ServiceWorker 中可以通過攔截特定類型的請求,例如接口請求或者資源請求,從而完成一些特殊的處理。
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('your-api-url.com')) {
event.respondWith(fetch(event.request).then((res) => {
return res.json().then((data) => {
return new Response(JSON.stringify(data));
});
}));
}
});
上述代碼中,我們監聽了 fetch 事件,如果檢測到該請求地址包含是某個API地址,則會使用 ServiceWorker 攔截該請求,然後獲取響應結果進行數據相關處理後返回。
五、ServiceWorkers是什麼意思
ServiceWorkers是指一類服務工作線程。ServiceWorker 是一種比較新的 HTML5 技術,它們被設計成運行在瀏覽器後台線程。
ServiceWorker 不會和瀏覽器標籤頁之間產生顯著的交互,這使得它們可以被用於離線應用程序、消息推送、後台數據同步和其他類似的任務。ServiceWorker 的 API 本質上就是 Web Worker API 的一種,但提供了更多的能力和一些不同的限制。
六、ServiceWorker和Web Worker
ServiceWorker 和 Web Worker 非常相似,它們都是後台線程,都不能訪問 DOM,提供了新的 JavaScript Worker 類,是 HTML5 中新添加的一種運行在瀏覽器後台的線程。
在 ServiceWorker 和 Web Worker 中,JavaScript 代碼是一個獨立的線程,不會阻塞主線程,允許同時做多件事情。
七、蘋果ServiceWorker
蘋果公司已經支持ServiceWorker技術,蘋果 Safari 瀏覽器在 2017 年 6 月份開始支持ServiceWorker 的註冊和使用,這對 PWA 應用的普及有着極為重要的意義。
八、Service workers與負責可靠實時交付的網絡應用程序
ServiceWorker 可以讓慢速和不可靠的網絡情況下的 Web 應用程序依然能夠擁有較好的用戶體驗。通過 ServiceWorker 的事件監聽功能,開發者可以在網絡離線的情況下,選擇香港或者本地緩存提供用戶一些基礎信息,避免 Web 應用程序傳輸許多陳舊和冗餘的數據。
此外,Service Worker 還為開發者提供了對本地緩存的實時控制功能,可以根據具體情況靈活調整緩存策略,可以選擇在頁面初始化或者在網絡上下文變化之後更新緩存。
九、Service Worker在瀏覽器的支持情況
目前支持ServiceWorker 的主流瀏覽器有:
- Chrome 45+
- Firefox 44+
- Opera 32+
- Edge 17+
- Safari 11.1+
Safari 目前僅支持 HTTPS 環境下的 ServiceWorker。
十、Service Workers的完整示例代碼
const CACHE_NAME = 'my-site-cache-v1';
const URLS_TO_CACHE = [
'/',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.png',
'/pages/offline.html'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => {
return cache.addAll(URLS_TO_CACHE);
})
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => {
if (response) {
return response;
}
return fetch(event.request);
})
.catch(() => {
return caches.match('/pages/offline.html');
})
);
});
self.addEventListener('activate', (event) => {
const cacheWhitelist = ['my-site-cache-v2'];
event.waitUntil(
caches.keys()
.then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
.then(() => {
return self.clients.claim();
})
);
});
上述代碼就是一個 ServiceWorker 實現離線緩存的完整代碼示例。它安裝和激活之後就會緩存指定的內容,後面在網絡不可達的情況下,會從緩存中讀取相應資源。如果緩存不存在,會返回缺省的 offline.html 頁面。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/291979.html