Service Worker的核心能力是拦截并重写fetch请求,需显式监听且仅对HTTPS生效;其缓存策略、生命周期管理及业务语义适配需手动设计,无开箱即用的“银弹”。
Service Worker 本身不是“魔法”,它带来的变革取决于你用它解决什么问题——离线能力、资源预缓存、后台同步、消息推送,这些功能都得自己写逻辑,不是注册一个脚本就自动生效。
这是它最核心的能力:在页面发起 fetch 或 XMLHttpRequest 时,SW 可以捕获请求、返回缓存、转发到网络、甚至合成响应。但要注意:
localhost 是例外)self.addEventListener('fetch', ...) 显式监听,不写就不会拦截iframe、、 等导航类请求,除非显式匹配 request.destination === 'document'
cache.put() 和 cache.match() 操作的是 Cache 对象,和 localStorage 完全无关。常见误区:
cache.keys() 返回的是 Request 对象,不是字符串 URL,不能直接 console.log 出可读地址
https://a.com/ 和 https://a.com/?t=1 是两个不同缓存项cache.delete() 或 cache.addAll() 就更新 SW 版本,旧缓存会一直留着,新 SW 拿不到cache.addAll() 遇到任一资源失败就会整体回滚,不适合混入不确定可用的第三方 URLSW 不是“启动即运行”,它有明确的状态流转:
install 阶段里如果 event.waitUntil() 中的 Promise 拒绝,安装失败,SW 不会进入 waiting 状态waiting 状态,直到所有旧页面关闭或手动调用 skipWaiting(),否则不会 activate
activate 阶段适合清理旧缓存(用 cache.keys().then(keys => keys.forEach(...))),但此时 fetch 还没接管,别在这儿做网络请求activate 是否完成真正难的不是注册 SW,而是设计缓存粒度、降级路径和版本迁移逻辑——比如一个 JSON 接口该不该缓存?缓存多久?失效后怎么通知页面重试?这些没法靠工具自动生成,得结合业务接口语义来判断。