当前位置: 首页 > 后端技术 > Node.js

处理

时间:2023-04-03 20:13:09 Node.js

ServiceWorker图片加载失败处理ServiceWorker图片加载失败处理参考文档gitclonehttps://gitee.com/wjj0720/Service-Worker.gitrunnpminpmstartaccesshttp://127.0.0.1:3000/pages/index.html打开控制台刷新(由于demo是post-loading,需要刷新才能看到效果)ctrl+c结束节点服务,重新刷新页面(从缓存中读取仍然显示page)Introduction背景有一个困扰网络用户多年的问题——网络连接丢失。之前的尝试-AppCache-似乎是一个很好的方法,但是,它假设您会遵循很多规则,如果您不严格遵守这些规则,它会搞砸您的应用程序。ServiceWorkers最终要解决这些问题。虽然ServiceWorker的语法比AppCache更复杂,但是你可以使用JavaScript来更精细地控制AppCache的静默行为。有了它,您可以解决当前的离线应用问题,同时做更多事情。ServiceWorker允许你的应用程序首先访问本地缓存资源,因此当它处于离线状态时,它仍然可以在通过网络接收更多数据之前提供基本功能(通常称为OfflineFirst)。这是原生应用已经支持的功能,也是原生应用比网页应用更受欢迎的主要原因。什么是服务人员?ServiceWorker是浏览器在后台启动的一个serviceworker线程功能和特点:1.一个独立的工作线程,而且只有一个。2.一旦安装就永远存在,除非卸载3.需要的时候可以直接唤醒,不需要的时候自动休眠(这里有个坑)4.可以代理请求返回,缓存文件,和缓存文件可以使用网页进程抓取5.可以向客户端推送消息6.不能直接操作DOM7.出于安全考虑,必须工作在HTTPS/localhost环境8.异步实现,大部分是内部通过Promise实现9.基于[webworker](http://www.ruanyifeng.com/blog/2018/07/web-worker.html)使用1.注册//兼容性判断if("serviceWorker"innavigator){//一般考虑加载问题windoeLoadafter.onloadwindow.addEventListener("load",function(){//scope参数是可选的,可以用来指定你希望serviceworker控制的内容的子目录navigator.serviceWorker.register("/sw.js",{scope:'/'}).then(function(registration){//注册成功console.log("ServiceWorker注册成功,范围:",registration.scope)}).catch(function(err){//注册失败console.log("ServiceWorker注册失败:",err)});})}2。使用constprecacheVersion=2constprecacheName="precache-v"+precacheVersionvarprecacheFiles=["/pages/index.html","/images/dmx.jpg","/images/broken.png"]/*Update*SW.js浏览器会自动检查差异*Changeoccursinstalleventistriggered此时,旧的SW还在工作,newSW进入等待状态*注意此时没有替换接管。当您打开的页面关闭时,旧的SW将被杀死。*新的SW开始接管页面的缓存资源。一旦新的SW接管,就会触发activate事件。*/self.addEventListener("install",e=>{console.log("[ServiceWorker]Installed")//skipWaiting()方法跳过等待状态,直接进入activate阶段self.skipWaiting()e.waitUntil(caches.open(precacheName).then(cache=>{//如果其中一个加载失败,则表示--本次启动GG).then(function(){////缓存成功//});}))})self.addEventListener("activate",e=>{console.log("[ServiceWorker]Activated")e.waitUntil(caches.keys().then(cacheNames=>{returnPromise.all(cacheNames.map(thisCacheName=>{if(thisCacheName.includes("precache")&&thisCacheName!==precacheName){returncaches.delete(thisCacheName)}}))}))//更新客户端//self.clients.claim()})//监听页面请求(不仅仅是js请求)self.addEventListener("fetch",e=>{e.respondWith(caches.match(e.request).then(response=>{//使用缓存缓存if(response){returnresponse}returnfetch(e.request).then(fetchResponse=>{//console.log('s-->',fetchResponse);if(fetchResponse.ok)returnfetchResponse;//如果加载失败,如果库存为图片,则返回默认图片if(isImage(e.request)){returnreturnBrokenImg()}}).catch(err=>{if(isImage(e.request)){returnreturnBrokenImg()}})}))})functionisImage(fetchRequest){returnfetchRequest.method==="GET"&&fetchRequest.destination==="image";}functionreturnBrokenImg(){返回caches.match('/images/broken.png').then(response=>response)}//从页面监听消息self.addEventListener('message',function(message,e){console.log('Datareceivedbyservice--->',message,e);sendMessageToPage('beepbeep')});//向页面发送消息functionsendMessageToPage(msg){self.clients.matchAll().then(函数(客户){如果(客户&&客户。长度){clients.forEach(function(client){client.postMessage(msg);})}})}3、除了浏览器触发外,如果24小时内没有更新,客户端更新会强制更新这意味着在最坏的情况下,ServiceWorker将每天更新一次//客户端更新方法:将版本保存在localStorage中,并在运行时进行比较varversion='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...