页面改完发上去,用户那边刷新五六次还是旧标题,DevTools 的 Application 里能看到两个版本的 precache 同时存在。乍看像缓存或者权限的锅,追下去往往不是。
self.addEventListener('install', () => self.skipWaiting())
self.addEventListener('activate', (e) => {
e.waitUntil(caches.keys().then(ks => Promise.all(
ks.filter(k => k !== CACHE).map(k => caches.delete(k)))))
})
追下去是这么回事:新的 SW 装完停在 waiting 状态,旧的还控制着页面,所有请求继续走旧缓存。skipWaiting 和 clients.claim 没调用,用户不关掉全部标签页就换不过来。
「Service Worker 旧缓存」这类改动最怕改一半,回滚脚本先准备好,再动生产。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。
能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。报错里带路径的,先去看那个路径在不在、权限对不对。
同一份配置存在多处的,先确认改的是被加载的那一份。
具体做法是,注册时监听 updatefound,新 SW 进入 installed 后提示用户刷新;在 activate 里清掉旧版本缓存,只保留当前 CACHE_NAME;确实要立刻生效就调用 skipWaiting,但放在用户确认之后,别把填了一半的表单刷掉。
验收就看一点,关掉标签页重开就是新版本,Application 里只剩一个缓存名。
