使用前提
- 站点必须是https的,不过本地开发若是localhost访问,则本地可以是http协议
- 浏览器支持情况,数据来源,
- SW里面的API要求是异步的,所以localStorage不能使用,下面的demo可以看到大量的promise
基础使用
scope
- scope作用域,一开始以为是同静态资源的作用域,后来才个发现这个作用域是hmtl的作用域,即只要html页面在这个作用域里,那页面的请求就会被fetch回调捕捉到。
下面的sw.js的路径是/
,或是把sw.js的Header加上``头,当前涉及到运维的事都会比较麻烦啦。所以就是前端把sw.js放在/下会简单些。
设置成功后就输出这样子:reg success with scope https://domain.com/sw/
navigator.serviceWorker.register('/sw.js', { scope: '/'}) .then(reg => { console.log('reg success with scope', reg.scope) }) .catch(err => { console.log('serviceWorker reg fail', err) })复制代码
/** * * 改了这个文件,在浏览器里禁用了缓存,sw.js也不会再加载,在index.html里加上时间戳就会重新加载 */const VERSION = 'v2'self.addEventListener('install', onInstall)self.addEventListener('activate', onActivate)self.addEventListener('fetch', onFetch)function onInstall(event) { // waitUntil 的第一个参数是Promise event.waitUntil( Promise.all([ self.skipWaiting(), // caches,不是cache caches.open(VERSION).then(cache => { // 在某一个cache集合里添加 return cache.addAll([ // 这里的路径是相对于reg的scope的,而是网站的root // 所以推荐写绝对路径 '/0.0.js', '/2.2.js', '/3.3.js', '/4.4.js', ]) }) ]) )}function onActivate(event) { let cacheWhiteList = [VERSION] event.waitUntil( caches.keys().then(function (keys) { return Promise.all(keys.map(function(key) { if (cacheWhiteList.indexOf(key) === -1) { // 删除某一个Cache集合 return caches.delete(key).then(suc => { return clients.claim() }) } // 强制更新service worker return clients.claim() })) }) )}function onFetch(event) { let url = new URL(event.request.url) if (url.pathname !== event.request.pathname)) { return event.respondWith( fetch(event.request) ) } // index.html的请求也会进来 event.respondWith( caches.match(event.request).then(resp => { return resp || fetch(event.request, { credentials: 'omit' // 不发送cookie }).then(response => { const cacheKey = VERSION return caches.open(cacheKey).then(cache => { // put 得是某一个cache cache.put(event.request, response.clone()).then(() => { }).catch((e) => { }) return response }) }) }) )}复制代码