最近看Vue的官方文档的时候,发现没有网的时候,页面还是可以被刷出来,一看…恩,serviceWorker
我的博客也要来一套,走起~

先看看Vue是怎么实现的
https://cn.vuejs.org/service-worker.js

要实现的效果

  • 请求资源成功,缓存进serviceWorker
  • 没网的时候,浏览器从serviceWorker取出资源
  • 资源更新时,会拉去新的资源
  • 有一天不想用serviceWorker了,可以卸载

1. Service Worker

Service Worker采用JavaScript控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是网络不可用)下的表现。

  • Service worker运行在worker上下文,因此它不能访问DOM。
  • 相对于驱动应用的主JavaScript线程,它运行在其他线程中,所以不会造成阻塞。
  • 出于安全考量,Service workers只能由HTTPS承载,毕竟修改网络请求的能力暴露给中间人攻击会非常危险。
  • 被install后就永远存在,除非被手动卸载

2. 实现资源拦截

请求成功时,正常返回请求内容,将资源缓存起来。没网的时候返回缓存资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 注册Sevice worker
window.addEventListener("load", event => {
// 判断浏览器是否支持
if ("serviceWorker" in navigator) {
window.navigator.serviceWorker
.register("/sw.js", {
scope: "/"
})
}
});

// 资源拦截
const VERSION = '1.0.0'
this.addEventListener("fetch", event => {
event.respondWith(
caches.match(event.request).then(response => {
let request = event.request.clone();
return fetch(request).then(httpRes => {
// http请求的返回已被抓到,可以处置了。
// 请求失败了,直接返回失败的结果就好了。。
if (!httpRes || httpRes.status !== 200) {
return httpRes;
}

// 请求成功的话,将请求缓存起来。
let responseClone = httpRes.clone();
caches.open(VERSION).then(cache => {
cache.put(event.request, responseClone);
});

return httpRes;
}, err => {
// 如果 Service Workder 之前存储了该资源,返回该资源
if (response) {
return response;
}
});
})
);
});

断网了再刷新这个页面试试,可以了~

参考资料