Service Worker 实现离线页面访问
最近看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;
}
});
})
);
});
断网了再刷新这个页面试试,可以了~