Service Worker 图片加载失败处理
栏目: JavaScript · 发布时间: 5年前
内容简介:/*新
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. 注册 ```js // 兼容判断 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('嘀嘀嘀'); });
5. 应用案例
1. 拦截图片加载失败 返回默认图片 案例 https://bitsofco.de/handling-broken-images-with-service-worker/ 2. 蓝湖 https://lanhuapp.com/
### 新鲜货 1. https://github.com/jiahaog/nativefier#how-it-works 3. https://imgcook.taobao.org/project
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- .net加载失败的程序集重新加载
- 记一次Fresco加载图片失败的分析
- 【视频教程】-图片加载失败模块设计-冰山工作室-沙翼-web前端
- 快速失败机制 & 失败安全机制
- 通过不断地失败来避免失败,携程混沌工程实践
- 快速失败(fail-fast)和安全失败(fail-safe)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM国际大学生程序设计竞赛题解
赵端阳//袁鹤 / 电子工业 / 2010-7 / 39.00元
随着各大专院校参加ACM/ICPC热情的高涨,迫切需要有关介绍ACM国际大学生程序设计竞赛题解的书籍。《ACM国际大学生程序设计竞赛题解(2)》根据浙江大学在线题库的部分题目,经过分类、筛选、汇编,并进行了解答(个别特别简单或者特别复杂的题目未选择),比较详细地分析和深入浅出地讲解了解题的方法和用到的算法。题目的类型包括基础编程、模拟、字符串处理、搜索、动态规划、回溯、图论、几何和数学题。 ......一起来看看 《ACM国际大学生程序设计竞赛题解》 这本书的介绍吧!