摘要:圖片加載失敗處理參考文檔運行訪問打開控制臺刷新由于做的是后加載需刷新后看效果結束服務再次刷新頁面從緩存里面讀取依然顯示頁面簡介背景有一個困擾用戶多年的難題丟失網絡連接。一旦新的接管,則會觸發事件。
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 結束node服務 再次刷新頁面(從緩存里面讀取 依然顯示頁面)簡介
背景
有一個困擾 web 用戶多年的難題——丟失網絡連接。之前的嘗試 — AppCache — 看起來是個不錯的方法,但是,它假定你使用時會遵循諸多規則,如果你不嚴格遵循這些規則,它會把你的APP搞得一團糟。Service worker 最終要去解決這些問題。雖然 Service Worker 的語法比 AppCache 更加復雜,但是你可以使用 JavaScript 更加精細地控制 AppCache 的靜默行為。有了它,你可以解決目前離線應用的問題,同時也可以做更多的事。 Service Worker 可以使你的應用先訪問本地緩存資源,所以在離線狀態時,在沒有通過網絡接收到更多的數據前,仍可以提供基本的功能(一般稱之為 Offline First)。這是原生APP 本來就支持的功能,這也是相比于 web app,原生 app 更受青睞的主要原因。
什么是Service Worker ?
Service Worker是瀏覽器在后臺啟動的一條服務Worker線程
功能和特性:
1.一個獨立的 worker 線程,且只有一個。 2.一旦被 install,就永遠存在,除非被 uninstall 3.需要的時候可以直接喚醒,不需要的時候自動睡眠(此處有坑) 4.可代理請求和返回,緩存文件,緩存的文件可以被網頁進程取到 5.能向客戶端推送消息 6.不能直接操作 DOM 7.出于安全的考慮,必須在 HTTPS/localhost 環境下才能工作 8.異步實現,內部大都是通過 Promise 實現 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 參數是選填的,可以被用來指定你想讓 service worker 控制的內容的子目錄 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 瀏覽器會自動檢查差異性 * 發生變更 install 事件被觸發 此時,舊的 SW 還在工作,新的 SW 進入 waiting 狀態。 * 注意,此時并不存在替換接管,當你現在已經打開的頁面關閉時,那么舊的 SW 則會被 kill 掉。 * 新的 SW 就開始接管頁面的緩存資源。 一旦新的 SW 接管,則會觸發 activate 事件。 */ self.addEventListener("install", e => { console.log("[ServiceWorker] Installed") // skipWaiting() 方法跳過 waiting 狀態,然后會直接進入 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() }) // 監聽頁面的請求 (不僅僅是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) } // 監聽頁面發來的消息 self.addEventListener("message", function (message, e) { console.log("service接受到的數據--->", message, e); sendMessageToPage("嘟嘟嘟") }); // 向頁面發送消息 function sendMessageToPage (msg) { self.clients.matchAll().then(function (clients) { if (clients && clients.length) { clients.forEach(function (client) { client.postMessage(msg); }) } }) }
3.客戶端更新
除了由瀏覽器觸發更新之外,如果24小時沒有更新,會強制更新。這意味著最壞情況下Service Worker會每天更新一次
//客戶端更新方法: localStorage 存下 版本 運行時候對比 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.客戶端消息
// 監聽serviceWorker 消息 navigator.serviceWorker.addEventListener("message", function (event) { // 接受數據, console.log("頁面接受的數據:", event); }); // 發送消息 document.getElementById("sendMSG").addEventListener("click", function () { console.log("綁定點擊事件,點擊后發送數據"); navigator.serviceWorker.controller.postMessage("嘀嘀嘀"); });
應用案例
1. 攔截圖片加載失敗 返回默認圖片 案例 https://bitsofco.de/handling-broken-images-with-service-worker/ 2. 藍湖 https://lanhuapp.com/新鮮貨
https://github.com/jiahaog/na...
https://imgcook.taobao.org/pr...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101102.html
摘要:生命周期的生命周期和網頁完全不相關。意即會作用于整個源地址上。激活安裝完之后下一步即激活。同時檢查響應類型是否為,即檢查請求是否同域。創建新的的過程將會啟動,然后觸發事件。可以利用劫持網絡連接和偽造響應數據。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協議共享,BY Troland。 本系列持續更新中,Github 地址請查閱這里。 這是 JavaScript 工...
摘要:誕生之初,是單線程的。當接收到服務端的響應之后,便通過回調函數執行之后的操作。沖鋒基于事件驅動。擁有攔截請求消息推送靜默更新地理圍欄等服務。控制時處于兩種狀態之一終止以節省內存監聽獲取和消息事件。支持的所有事件五銷毀瀏覽器決定是否銷毀。 這次體驗一種新的博客風格,我們長話短說,針針見血。 showImg(https://segmentfault.com/img/remote/14600...
摘要:可以發送通知消息以再次吸引用戶并留住他們。在即時通訊等使用情形中,一條消息可將最多的有效負載傳送至客戶端應用。瀏覽器的的消息推送主要依賴,服務端消息推送傳遞到,然后再由推送到客戶端。 引言 Progressive Web App, 簡稱 PWA,是提升 Web App 的體驗的一種新方法,能給用戶原生應用的體驗。Service Worker 是 PWA 中的重要一部分。Service ...
閱讀 1015·2021-09-26 09:55
閱讀 3556·2021-09-24 10:30
閱讀 1364·2021-09-08 09:36
閱讀 2552·2021-09-07 09:58
閱讀 603·2019-08-30 15:56
閱讀 764·2019-08-29 18:32
閱讀 3593·2019-08-29 15:13
閱讀 1840·2019-08-29 13:49