var cacheStorageKey = 'minimal-pwa-1';
var cacheList = [
'/',
'index.html'
// ...[list]
]
console.log('>>>>>>self:', self); // --> 浏览器中 == window obj
// 监听service worker安装事件
self.addEventListener('install', e => { // e => event 事件
// waitUntil()方法是确保 Service Worker 在 waitUntil() 里面的代码执行完毕之后安装完成
e.waitUntil(
// caches.open(key) // 创建了一个缓存
caches.open(cacheStorageKey)
// cache.addAll(list) 把一组资源全部缓存到对应的key中
.then(cache => cache.addAll(cacheList))
// sw.js 文件有更新 表示Service Worker 版本更新
/*
版本更新时,此时已经处于激活状态的旧的 Service Worker 还在运行,
新的 Service Worker 完成安装后会进入 waiting 状态。
直到所有已打开的页面都关闭,旧的 Service Worker 自动停止,
新的 Service Worker 才会在接下来重新打开的页面里生效。
*/
/*
self.skipWaiting()方法跳过 waiting 状态,然后会直接进入 activate 阶段。
接着在 activate 事件发生时,通过执行 self.clients.claim() 方法,
更新所有客户端上的 Service Worker。
*/
.then(() => self.skipWaiting())
)
})
// 每次任何被 Service Worker 控制的资源被请求到时,都会触发 fetch 事件,
// 监听 fetch 事件 fetch:区别与ajax的一种请求方式 返回结果是 promise 类型
self.addEventListener('fetch', function (e) {
// e.respondWith(),用来劫持我们的http响应
e.respondWith(
// 在缓存中查找是否有匹配的请求
caches.match(e.request).then(function (response) {
// 如果 Service Worker 有自己的返回,就直接返回,减少一次 http 请求
if (response != null) {
return response
}
// 没有则那就得直接请求真实远程服务
var request = event.request.clone(); // 把原始请求拷过来
return fetch(fetchRequest).then(function (response) {
if (!response || response.status !== 200 || !response.headers.get('Content-type').match(/image/)) {
// 不是图片 直接返回请求
return response;
}
// 是图片 复制两份
// 一份先存入缓存
var responseToCache = response.clone();
caches.open(cacheStorageKey)
.then(function (cache) {
cache.put(event.request, responseToCache);
});
// 一份发给页面
return response;
}
);
})
)
})
// 监听安装后 是否被激活
self.addEventListener('activate', function (e) {
e.waitUntil(
Promise.all(
// 清理旧版本
caches.keys().then(cacheNames => {
return cacheNames.map(name => {
if (name !== cacheStorageKey) {
// 删除旧的缓存
return caches.delete(name)
}
})
})
).then(() => {
// 更新客户端
return self.clients.claim()
})
)
})