摘要:圖片加載失敗處理參考文檔運行訪問打開控制臺刷新由于做的是后加載需刷新后看效果結(jié)束服務(wù)再次刷新頁面從緩存里面讀取依然顯示頁面簡介背景有一個困擾用戶多年的難題丟失網(wǎng)絡(luò)連接。一旦新的接管,則會觸發(fā)事件。
Service Worker 圖片加載失敗處理
參考文檔
git clone https://gitee.com/wjj0720/Service-Worker.git 運行 npm i npm start 訪問 http://127.0.0.1:3000/pages/index.html 打開控制臺 刷新(由于demo做的是后加載 需刷新后 看效果) ctrl + c 結(jié)束node服務(wù) 再次刷新頁面(從緩存里面讀取 依然顯示頁面)簡介
背景
有一個困擾 web 用戶多年的難題——丟失網(wǎng)絡(luò)連接。之前的嘗試 — AppCache — 看起來是個不錯的方法,但是,它假定你使用時會遵循諸多規(guī)則,如果你不嚴格遵循這些規(guī)則,它會把你的APP搞得一團糟。Service worker 最終要去解決這些問題。雖然 Service Worker 的語法比 AppCache 更加復(fù)雜,但是你可以使用 JavaScript 更加精細地控制 AppCache 的靜默行為。有了它,你可以解決目前離線應(yīng)用的問題,同時也可以做更多的事。 Service Worker 可以使你的應(yīng)用先訪問本地緩存資源,所以在離線狀態(tài)時,在沒有通過網(wǎng)絡(luò)接收到更多的數(shù)據(jù)前,仍可以提供基本的功能(一般稱之為 Offline First)。這是原生APP 本來就支持的功能,這也是相比于 web app,原生 app 更受青睞的主要原因。
什么是Service Worker ?
Service Worker是瀏覽器在后臺啟動的一條服務(wù)Worker線程
功能和特性:
1.一個獨立的 worker 線程,且只有一個。 2.一旦被 install,就永遠存在,除非被 uninstall 3.需要的時候可以直接喚醒,不需要的時候自動睡眠(此處有坑) 4.可代理請求和返回,緩存文件,緩存的文件可以被網(wǎng)頁進程取到 5.能向客戶端推送消息 6.不能直接操作 DOM 7.出于安全的考慮,必須在 HTTPS/localhost 環(huán)境下才能工作 8.異步實現(xiàn),內(nèi)部大都是通過 Promise 實現(xiàn) 9.基于[web worker](http://www.ruanyifeng.com/blog/2018/07/web-worker.html)使用
1.注冊
// 兼容判斷 if ("serviceWorker" in navigator) { // 一般考慮加載問題 windoe.onload后加載 window.addEventListener("load", function() { // scope 參數(shù)是選填的,可以被用來指定你想讓 service worker 控制的內(nèi)容的子目錄 navigator.serviceWorker.register("/sw.js", {scope: "/"}) .then(function(registration) { // 注冊成功 console.log( "ServiceWorker registration successful with scope: ", registration.scope ) }) .catch(function(err) { // 注冊失敗 console.log("ServiceWorker registration failed: ", err) }); }) }
2.使用
const precacheVersion = 2 const precacheName = "precache-v" + precacheVersion var precacheFiles = [ "/pages/index.html", "/images/dmx.jpg", "/images/broken.png" ] /*更新 * SW.js 瀏覽器會自動檢查差異性 * 發(fā)生變更 install 事件被觸發(fā) 此時,舊的 SW 還在工作,新的 SW 進入 waiting 狀態(tài)。 * 注意,此時并不存在替換接管,當(dāng)你現(xiàn)在已經(jīng)打開的頁面關(guān)閉時,那么舊的 SW 則會被 kill 掉。 * 新的 SW 就開始接管頁面的緩存資源。 一旦新的 SW 接管,則會觸發(fā) activate 事件。 */ self.addEventListener("install", e => { console.log("[ServiceWorker] Installed") // skipWaiting() 方法跳過 waiting 狀態(tài),然后會直接進入 activate 階段 self.skipWaiting() e.waitUntil( caches.open(precacheName).then(cache => { // 如果其中有一個 加載失敗 那就代表著--這次啟動 GG return cache.addAll(precacheFiles) // cache.put(request, response).then(function() { // // 成功緩存 // }); }) ) }) self.addEventListener("activate", e => { console.log("[ServiceWorker] Activated") e.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames.map(thisCacheName => { if ( thisCacheName.includes("precache") && thisCacheName !== precacheName ) { return caches.delete(thisCacheName) } }) ) }) ) // 更新客戶端 // self.clients.claim() }) // 監(jiān)聽頁面的請求 (不僅僅是js請求) self.addEventListener("fetch", e => { e.respondWith( caches.match(e.request).then(response => { // 有緩存走緩存 if (response) { return response } return fetch(e.request) .then(fetchResponse => { // console.log("s-->", fetchResponse); if (fetchResponse.ok) return fetchResponse; // 加載失敗的情況下 入股是圖片 則返回默認圖片 if (isImage(e.request)) { return returnBrokenImg() } }).catch(err => { if ( isImage(e.request) ) { return returnBrokenImg() } }) }) ) }) function isImage(fetchRequest) { return fetchRequest.method === "GET" && fetchRequest.destination === "image"; } function returnBrokenImg () { return caches.match("/images/broken.png").then(response => response) } // 監(jiān)聽頁面發(fā)來的消息 self.addEventListener("message", function (message, e) { console.log("service接受到的數(shù)據(jù)--->", message, e); sendMessageToPage("嘟嘟嘟") }); // 向頁面發(fā)送消息 function sendMessageToPage (msg) { self.clients.matchAll().then(function (clients) { if (clients && clients.length) { clients.forEach(function (client) { client.postMessage(msg); }) } }) }
3.客戶端更新
除了由瀏覽器觸發(fā)更新之外,如果24小時沒有更新,會強制更新。這意味著最壞情況下Service Worker會每天更新一次
//客戶端更新方法: localStorage 存下 版本 運行時候?qū)Ρ? var version = "precache-v3" navigator.serviceWorker.register("/sw.js").then(function (reg) { if (localStorage.getItem("sw_version") !== version) { reg.update().then(function () { localStorage.setItem("sw_version", version) }); } })
4.客戶端消息
// 監(jiān)聽serviceWorker 消息 navigator.serviceWorker.addEventListener("message", function (event) { // 接受數(shù)據(jù), console.log("頁面接受的數(shù)據(jù):", event); }); // 發(fā)送消息 document.getElementById("sendMSG").addEventListener("click", function () { console.log("綁定點擊事件,點擊后發(fā)送數(shù)據(jù)"); navigator.serviceWorker.controller.postMessage("嘀嘀嘀"); });
應(yīng)用案例
1. 攔截圖片加載失敗 返回默認圖片 案例 https://bitsofco.de/handling-broken-images-with-service-worker/ 2. 藍湖 https://lanhuapp.com/新鮮貨
https://github.com/jiahaog/na...
https://imgcook.taobao.org/pr...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/101102.html
摘要:生命周期的生命周期和網(wǎng)頁完全不相關(guān)。意即會作用于整個源地址上。激活安裝完之后下一步即激活。同時檢查響應(yīng)類型是否為,即檢查請求是否同域。創(chuàng)建新的的過程將會啟動,然后觸發(fā)事件。可以利用劫持網(wǎng)絡(luò)連接和偽造響應(yīng)數(shù)據(jù)。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工...
摘要:誕生之初,是單線程的。當(dāng)接收到服務(wù)端的響應(yīng)之后,便通過回調(diào)函數(shù)執(zhí)行之后的操作。沖鋒基于事件驅(qū)動。擁有攔截請求消息推送靜默更新地理圍欄等服務(wù)。控制時處于兩種狀態(tài)之一終止以節(jié)省內(nèi)存監(jiān)聽獲取和消息事件。支持的所有事件五銷毀瀏覽器決定是否銷毀。 這次體驗一種新的博客風(fēng)格,我們長話短說,針針見血。 showImg(https://segmentfault.com/img/remote/14600...
摘要:可以發(fā)送通知消息以再次吸引用戶并留住他們。在即時通訊等使用情形中,一條消息可將最多的有效負載傳送至客戶端應(yīng)用。瀏覽器的的消息推送主要依賴,服務(wù)端消息推送傳遞到,然后再由推送到客戶端。 引言 Progressive Web App, 簡稱 PWA,是提升 Web App 的體驗的一種新方法,能給用戶原生應(yīng)用的體驗。Service Worker 是 PWA 中的重要一部分。Service ...
閱讀 1027·2021-09-26 09:55
閱讀 3573·2021-09-24 10:30
閱讀 1374·2021-09-08 09:36
閱讀 2558·2021-09-07 09:58
閱讀 609·2019-08-30 15:56
閱讀 774·2019-08-29 18:32
閱讀 3622·2019-08-29 15:13
閱讀 1847·2019-08-29 13:49