Service Worker缓存预热时为什么关键资源没被正确缓存?

令狐智慧 阅读 31

我在用Service Worker做缓存预热时遇到问题,按照教程在install事件里预缓存了关键资源列表,但实际访问时发现某些CSS文件还是走网络请求了。

代码写的是这样的:


self.addEventListener('install', (e) => {
  e.waitUntil(
    caches.open('v1').then(cache => {
      return cache.addAll([
        '/index.html',
        '/styles/main.css', // 这个文件没被缓存
        '/scripts/app.js'
      ]);
    })
  );
});

我检查过路径没问题,但控制台提示”Failed to load resource”。奇怪的是app.js能成功缓存,main.css却一直显示503,难道是服务器配置的问题吗?或者需要在activate事件里做额外处理?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
UX馨然
UX馨然 Lv1
我也踩过这个坑。你遇到的问题很可能不是服务器配置问题,而是Service Worker在缓存CSS文件时,默认没有正确处理请求的Content-Type或者请求头的问题。

你用cache.addAll()缓存资源时,它其实会为每个路径发送一个默认的GET请求去拉资源。如果服务器在响应CSS文件时没有正确设置Content-Type: text/css,浏览器可能会拒绝将这个响应缓存下来,尤其是在某些严格的模式下。

更稳妥的做法是手动发起请求,并明确指定请求的mode、headers等,比如:

self.addEventListener('install', (e) => {
e.waitUntil(
caches.open('v1').then(cache => {
return cache.add(new Request('/styles/main.css', {
headers: new Headers({
'Accept': 'text/css'
}
})).then(() => {
return cache.addAll([
'/index.html',
'/scripts/app.js'
]);
});
})
);
});


我当时也是发现CSS资源经常莫名缓存失败,后来才发现是浏览器对CSS的加载有更严格的校验。你看到的503可能不是服务器问题,而是缓存加载失败之后触发的fallback问题。

另外,别忘了在activate事件里清理旧缓存,避免旧版本影响新缓存生效。
点赞 9
2026-02-05 09:09
南宫小敏
cache.addAll 遇到 4xx 或 5xx 响应就会失败,但不会中断 e.waitUntil,导致部分资源没缓存。建议改用 cache.add 单独缓存每个资源,或者检查服务器是否对 CSS 文件返回了错误响应。

self.addEventListener('install', (e) => {
e.waitUntil(
caches.open('v1').then(cache => {
return Promise.all([
'/index.html',
'/styles/main.css',
'/scripts/app.js'
].map(url => cache.add(url)))
})
);
});


就这样。
点赞 10
2026-01-31 10:04