service worker 拦截网络请求的核心是通过 fetch 事件主动接管响应逻辑,依赖注册、安装、拦截三步闭环:注册需在 https 或 localhost 下进行并检查兼容性;install 阶段预存静态资源至带版本号的缓存;fetch 事件中用 event.respondwith() 实时分流并决定响应来源;activate 阶段清理旧缓存并立即激活新版。

Service Worker 拦截网络请求的核心,是通过 fetch 事件 在请求发出时主动接管响应逻辑,而不是被动等待“离线发生”。它不依赖网络状态检测,而是每次请求都做判断:该从缓存取,还是走网络?关键在注册、安装、拦截三步闭环,缺一不可。
注册必须在安全上下文下进行
Service Worker 只能在 HTTPS 或 localhost 环境注册。主页面 JS 中需先检查兼容性,再注册:
- 用
if ('serviceWorker' in navigator)判断支持情况 - 在
window.addEventListener('load', ...)中调用navigator.serviceWorker.register('/sw.js') -
sw.js建议放在网站根目录;若放其他路径,需显式指定{ scope: '/' }才能控制全站请求
install 阶段预存静态资源
这是离线可用的前提——提前把确定不变的核心文件存进缓存,不是等用户访问时才缓存。
- 在
sw.js的install事件里调用caches.open('static-v1')创建带版本号的缓存空间 - 用
cache.addAll(['/', '/index.html', '/app.css'])预存资源,路径必须和页面实际发起的请求 URL 完全一致(含尾斜杠、查询参数) - 整个操作必须包裹在
event.waitUntil()中,否则安装可能中断,缓存写入失败
fetch 事件中实时决定响应来源
浏览器每发起一个匹配 scope 的请求(导航、fetch、资源加载),都会触发这个事件。你必须第一时间用 event.respondWith() 控制返回内容。
- 第一行就得写
event.respondWith(...),漏掉或放在条件分支里会导致默认网络行为生效,缓存逻辑失效 - 优先按请求类型分流:
request.destination === 'document'处理页面,'script'或'style'处理脚本样式,比单纯匹配 URL 更可靠 - 查缓存:
const cached = await caches.match(event.request);命中就直接返回,未命中则fetch(event.request) - 如需缓存新响应,记得先
response.clone()再cache.put(),因为 Response body 只能读一次 - 跨域请求(如 CDN、第三方 API)建议跳过拦截:
new URL(req.url).origin !== location.origin
activate 阶段清理旧缓存并接管页面
每次更新 sw.js 后,旧缓存不会自动删除,必须手动清理,否则用户可能加载到过期资源。
- 在
activate事件中调用caches.keys()获取所有缓存名 - 筛选出非当前版本的缓存(比如当前用
static-v2,就删掉static-v1) - 对每个待删缓存调用
caches.delete(key),同样用event.waitUntil()包裹 - 加上
self.skipWaiting()(在 install 中)和self.clients.claim()(在 activate 中),让新版 SW 立即激活并接管已有页面
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











