Service Worker
生命周期
安装 (Install) :
- 当 Service Worker 被注册后,会触发安装事件。此时,Service Worker 可以进行一些初始化工作,比如缓存静态资源。
- 安装完成后,Service Worker 会进入等待状态,等待激活。
激活 (Activate) :
- 安装完成后,会触发激活事件。此时,旧的 Service Worker 如果存在,可以被卸载,新的 Service Worker 可以接管控制。
- 这个阶段通常用于清理旧的缓存和其他不再需要的资源。
运行 (Run) :
- 激活后,Service Worker 进入运行状态,可以处理网络请求和其他事件。
- Service Worker 处于“运行中”状态时,可以通过 fetch 事件拦截网络请求,进行缓存、网络请求或其他处理。
更新 (Update) :
- Service Worker 会定期检查是否有新版本可用。如果检测到新版本,会触发安装事件,并进入安装和激活的流程。
- 可以通过
self.skipWaiting()
方法强制让新的 Service Worker 在激活时立即接管控制。
卸载 (Unregister) :
- 用户可以主动注销 Service Worker,此时会触发相应的卸载事件。
基础流程
==注意:版本信息直接写在service worker文件中的,作为常量==
第一次登陆时:
- 注册 v1.2.0
- 安装 v1.2.0
- 激活 v1.2.0
激活成功后:再刷新(第二次进入时)
- 监听到fetch变化 v1.2.0
- 重新注册 v1.2.0
每用caches.open
打开不同CACHES_NAME
时,缓存中就会有两个不同根据CACHES_NAME
命名的缓存内容
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const CACHES_NAME = "v1.2.1"
self.addEventListener('install', eveFnt => { console.log("安装完成",CACHES_NAME) self.skipWaiting() })
self.addEventListener('activate', async (event) => { console.log("激活成功", CACHES_NAME) })
self.addEventListener('fetch', event => { console.log("收到fetch", CACHES_NAME) })
|
缓存
基础
在install时,添加静态缓存,并使用
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 41 42
| const RESOURCES = [ '/index.css' ];
const CACHES_NAME = "v1.2.1"
self.addEventListener('install', eveFnt => { console.log("安装完成", CACHES_NAME) self.skipWaiting() eveFnt.waitUntil( caches.open(CACHES_NAME).then(cache => { return cache.addAll(RESOURCES) }) ) })
self.addEventListener('activate', async (event) => { console.log("激活成功", CACHES_NAME) })
self.addEventListener('fetch', event => { console.log("收到fetch", CACHES_NAME, event)
event.respondWith( caches.open(CACHES_NAME).then(function (cache) { return caches.match(event.request).then(function (response) { if (response) { return response; }
return fetch(event.request) }) }) ); })
|
缓存所有
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
| const CACHES_NAME = "v1.2.1"
self.addEventListener('install', eveFnt => { console.log("安装完成", CACHES_NAME) self.skipWaiting() })
self.addEventListener('activate', async (event) => { console.log("激活成功", CACHES_NAME) })
self.addEventListener('fetch', event => { console.log("收到fetch", CACHES_NAME, event)
event.respondWith( caches.open(CACHES_NAME).then(function (cache) { return caches.match(event.request).then(function (response) { if (response) { return response; }
return fetch(event.request).then(response => { if (!response || response.status !== 200 || response.type !== 'basic') { return response; }
caches.open(CACHES_NAME).then(cache => cache.put(event.request, response.clone()))
return response; }) }) }) ); })
|
缓存指定文件
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 41 42 43 44 45 46 47 48 49
| const RESOURCES = [ '/index.css', '/index.js' ];
const CACHES_NAME = "v1.2.1"
self.addEventListener('install', eveFnt => { console.log("安装完成", CACHES_NAME) self.skipWaiting() })
self.addEventListener('activate', async (event) => { console.log("激活成功", CACHES_NAME) })
self.addEventListener('fetch', event => { console.log("收到fetch", CACHES_NAME, event)
event.respondWith( caches.open(CACHES_NAME).then(function (cache) { return caches.match(event.request).then(function (response) { if (response) { return response; }
return fetch(event.request).then(response => { if (!response || response.status !== 200 || response.type !== 'basic') { return response; }
if (RESOURCES.some(resource => url.pathname === resource)) { const responseToCache = response.clone(); caches.open(CACHES_NAME).then(cache => cache.put(event.request, responseToCache)) } return response; }) }) }) ); })
|
其他
cache.put、cache.add、cache.addAll的区别
总结来说:
-
add
和 addAll
用于从网络获取并添加资源,而 put
用于直接将请求和响应对存入缓存。
-
add
和 addAll
不会覆盖现有缓存,而 put
会。
拦截请求
==Tips: 这些mockData还可以放在IndexedDB中,更灵活的控制数据==
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| const RESOURCES = [ '/index.css' ];
const mockData = { '/api/data1': { message: "这是数据1" }, '/api/data2': { message: "这是数据2" }, '/api/data3': { message: "这是数据3" }, '/api/data4': { message: "这是数据4" } }
const CACHES_NAME = "v1.3.1"
self.addEventListener('install', eveFnt => { console.log("安装完成", CACHES_NAME) self.skipWaiting() })
self.addEventListener('activate', async (event) => { console.log("激活成功", CACHES_NAME) })
self.addEventListener('fetch', event => { console.log("收到fetch", CACHES_NAME, event)
const url = new URL(event.request.url);
if (mockData[url.pathname]) { const responseData = mockData[url.pathname]; event.respondWith( new Response(JSON.stringify(responseData), { headers: { 'Content-Type': 'application/json' } }) );
return }
event.respondWith( caches.open(CACHES_NAME).then(function (cache) { return caches.match(event.request).then(function (response) { if (response) { return response; }
return fetch(event.request).then(response => { if (!response || response.status !== 200 || response.type !== 'basic') { return response; }
if (RESOURCES.some(resource => url.pathname === resource)) { const responseToCache = response.clone(); caches.open(CACHES_NAME).then(cache => cache.put(event.request, responseToCache)) } return response; }) }) }) ); })
|