介绍
service worker 是为了是的 web app 拥有和 native app相同的离线体验,消息推送体验
- 不能直接参与web交互行为
- 可以
- 后台消息传递
- 网络代理,转发请求,伪响应
- 离线缓存
- 消息推送
过程
- installing
- actived/error
- idle
- terminated/fetch-message
fetch 事件
- 当页面发送http请求,sevice workerk可以通过fetch 事件拦截请求,并给出自己的响应
message事件
- 双向的过程
利用 service worker
缓存文件
// 使用外部文件注册 service-worker.js
if (navigator.serviceWorker) {
navigator.serviceWorker.register('service-worker.js')
.then(function (registration) {
console.log('service worker 注册成功')
}).catch(function () {
console.log('service worker 注册失败')
})
}
- https 和 localhost 才能使用 service worker
service-worker
文件
var cacheFiles = [
'about.js',
'blog.js'
]
self.addEventListener('install',function (evt) {
evt.waitUntil(
cache.open('my-test-cache-v1').then(function (cache) {
return cache.addAll(cacheFiles);
})
)
})
- 首先定义了需要混测的文件数组
- 在
install
事件中,缓存这些文件 -
waitUntil
方法接受一个promise
对象,只有在该promise
对象成功resolve
之后,才会继续运行service-worker.js
-
cache
对象使用open
方法打开一个缓存,通过名称区分,通过addAll
缓存文件
拦截fetch
事件
想让浏览器使用缓存,需要拦截fetch事件
self.addEventListener('fetch',function (evt) {
evt.responseWith({
caches.match(evt.request).then(function (response) {
if (response) {
return response;
}
var request = evt.request.clone();
return fetch(request).then(function (response) {
// 总感觉判断条件有点问题
if (!response && response.status !== 200 && !response.headers.get('Content-type').match(/image/)) {
return response;
}
var responseClone = response.clone();
caches.open('my-test-cache-v1').then(function (cache) {
cache.put(evt.request, responseClone);
});
return response;
})
})
})
})
- 通过监听
fetch
事件,service worker 可以返回自己的响应 - 先检查缓存中是否有这个请求,有就直接响应
- service worker 请求通过fetch api 完成,对 response 对象进行过滤,查看是否是图片文件,不是就直接返回请求
- 如果是图片,就赋值一份,一份放到缓存中,一份响应。因为
request
或者response
属于stream
,只能使用一次
运行时间
- 取决于浏览器,
service worker
到底是在页面关闭后关闭还是在浏览器关闭之后关闭 - 因此不要定义一些全局变量
权限过大
- 当service worker有问题,会导致所有请求失败
- service worker需要质量高,容错行强