为什么我的Service Worker缓存策略导致页面刷新后内容没更新?

公孙凡敬 阅读 50

最近给项目加了Service Worker做静态资源缓存,但发现更新了JS文件后页面一直显示旧版本。明明已经用cache.first策略,还手动调用了clients.claim()skipWaiting(),可每次刷新都是旧代码。控制台也没报错,这是哪里出问题了?

我尝试过:


// sw.js
const staticCacheName = 'v1-static'; // 已经改过版本号了
self.addEventListener('install', e => {
  e.waitUntil(
    caches.open(staticCacheName)
      .then(cache => cache.addAll([
        '/index.html',
        '/main.js',
        '/styles.css'
      ]))
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => 
        response || fetch(event.request).then(r => {
          caches.open(staticCacheName).then(cache => cache.put(event.request, r));
          return r;
        })
      )
  );
});

清除浏览器缓存后第一次访问能拿到新文件,但之后再修改main.js保存,页面刷新还是旧内容。难道是缓存策略写错了?或者需要主动删除旧缓存?

我来解答 赞 11 收藏
二维码
手机扫码查看
1 条解答
轩辕富水
我之前踩过这个坑,问题出在缓存版本管理和旧缓存清理上。你现在的代码虽然改了版本号,但并没有真正清理掉旧的缓存内容,导致浏览器还是从旧缓存里取文件。

解决办法是,在Service Worker安装时主动清理掉旧版本的缓存。可以在install事件里加一段逻辑,把当前版本以外的缓存都删掉。像这样:


const staticCacheName = 'v2-static'; // 每次更新记得改版本号

self.addEventListener('install', e => {
e.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cache => {
if (cache !== staticCacheName) {
return caches.delete(cache);
}
})
);
}).then(() => {
return caches.open(staticCacheName).then(cache => {
return cache.addAll([
'/index.html',
'/main.js',
'/styles.css'
]);
});
})
);
});


另外要注意两点:第一,每次修改静态资源后,记得更新staticCacheName的版本号,不然新内容不会被缓存。第二,clients.claim()skipWaiting()确实能加快Service Worker的激活,但如果缓存没清理干净,还是会用回旧文件。

还有个小技巧,可以在fetch事件里加个判断,优先从网络获取最新资源,再更新缓存。这样能避免用户一直用旧版本的问题。类似这样:


self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
const fetchPromise = fetch(event.request).then(networkResponse => {
return caches.open(staticCacheName).then(cache => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
});
return response || fetchPromise;
})
);
});


总之记住,Service Worker的缓存策略要同时考虑版本管理、旧缓存清理和更新机制。这三个地方处理不好,就会出现你遇到的这种问题。
点赞 1
2026-02-16 09:06