核心是打破html与sw缓存更新死循环:html请求必须走网络(networkfirst/networkonly),js/css需带hash并严格匹配缓存key,上线时主动update、skipwaiting、claim,并配合服务端no-cache响应头。

核心是打破“旧 HTML 引用新资源失败”或“新 HTML 被跳过、仍走旧 SW 缓存”的死循环。关键不在删缓存,而在让 HTML 请求始终走网络,同时确保 JS/CSS 等资源缓存可被安全更新。
强制 HTML 请求不走缓存
Service Worker 对 document 类型请求(即页面主 HTML)必须采用 NetworkFirst 或 NetworkOnly 策略。不能让它命中过期的缓存版本:
- 在 fetch 事件中判断
event.request.destination === 'document' - 直接调用
fetch(event.request),不查 cache - 可加兜底:若网络失败,再 fallback 到预存的
offline.html或内联 HTML 字符串
静态资源缓存需带版本标识
JS/CSS 文件名本身带 hash(如 app.a1b2c3.js)只是基础。SW 缓存 key 必须与之严格对齐:
- 安装阶段缓存的 URL,必须和 HTML 中实际写的
<script src="..."></script>完全一致 - 避免用
caches.match(event.request.url)这类宽松匹配——它可能返回旧 hash 的文件 - 推荐用
caches.match(event.request),依赖 Request 对象完整 URL 和 headers 匹配
上线时主动触发 SW 更新与激活
用户访问时若还在用旧版 SW,新缓存根本不会生效:
- 注册后立即调用
registration.update(),显式拉取最新 SW 脚本 - 在 install 回调中加
self.skipWaiting() - 在 activate 回调中加
clients.claim(),让当前页立刻受控 - 避免依赖“关闭再打开页面”这类用户不可控行为
服务端配合减少缓存干扰
即使有 SW,HTTP 缓存头仍会影响首次加载或 SW 安装过程:
-
index.html响应头设为Cache-Control: no-cache, must-revalidate或no-store - 不要依赖
<meta http-equiv="Cache-Control">,微信等环境会忽略 - API 接口响应头加
Vary: Origin(如需跨域),避免 SW 拿错缓存










