You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vite React项目Service Worker静态资源缓存失效求助

解决Vite React应用Service Worker静态资源缓存失败问题

问题诊断

你的Service Worker install事件触发但资源未缓存,结合代码来看,主要存在以下几个核心问题:

  • cache.addAll未返回Promise:install事件中e.waitUntil需要等待缓存完成的Promise,但代码里cache.addAll(assets)没有return,导致SW可能在缓存操作完成前就提前激活。
  • Vite构建路径不匹配:生产环境下Vite会把src目录下的文件打包成带hash的资源(比如assets/main.[hash].js),你缓存的/src/main.jsx这类源文件路径在构建后根本不存在。
  • 跨域资源缓存错误:https://fonts.gstatic.com是目录而非具体资源,cache.addAll无法缓存目录;同时跨域资源需要服务器返回CORS头才能被正常缓存。
  • 缺少Fetch事件拦截逻辑:即使缓存成功,没有处理fetch事件的代码,浏览器会直接走网络请求,不会读取缓存内容。
  • 激活事件未处理旧缓存:旧缓存可能干扰新缓存的生效,导致资源无法被正确读取。

修复后的Service Worker代码

const staticCacheName = 'site-static-v1'; // 加版本号方便更新缓存
// 注意:生产环境请替换为Vite构建后的实际资源路径,或用workbox自动生成
const assets = [
    '/',
    '/index.html',
    '/manifest.json',
    // 示例:替换为Vite构建后的资源路径
    // '/assets/main.[hash].js',
    // '/assets/App.[hash].css',
    '/icons/UP-72x72.png',
    '/icons/UP-96x96.png',
    '/icons/UP-128x128.png',
    '/icons/UP-144x144.png',
    '/icons/UP-152x152.png',
    '/icons/UP-192x192.png',
    '/icons/UP-384x384.png',
    '/icons/UP-512x512.png',
    '/screenshots/UP-screenshots-1280x890.png',
    '/screenshots/UP-screenshots-828x1792.png',
    'https://fonts.googleapis.com/css2?family=Alata&family=Archivo+Black&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap',
    // 示例:替换为具体字体文件URL
    // 'https://fonts.gstatic.com/s/alata/v10/PbytFmztEwbIoce9zq56BDmX.woff2',
    '/assets/react.svg',
    '/vite.svg',
];

self.addEventListener("push", e => {
    const data = e.data ? e.data.json() : {};
    const title = data.title || "Default Title";
    const options = {
        body: data.body || "You have a new message.",
    };
    e.waitUntil(self.registration.showNotification(title, options));
});

self.addEventListener("install", e => {
    e.waitUntil(
        caches.open(staticCacheName).then(cache => {
            console.log("Caching static assets");
            // 返回Promise确保waitUntil等待缓存完成
            return cache.addAll(assets);
        }).catch(err => {
            console.error("缓存失败:", err);
        })
    );
});

self.addEventListener("activate", e => {
    e.waitUntil(
        caches.keys().then(keys => {
            // 删除旧版本缓存
            return Promise.all(keys.filter(key => key !== staticCacheName).map(key => caches.delete(key)));
        })
    );
    // 立即控制所有打开的页面
    self.clients.claim();
});

self.addEventListener("fetch", e => {
    // 优先使用缓存,缓存不存在时请求网络
    e.respondWith(
        caches.match(e.request).then(cachedResponse => {
            return cachedResponse || fetch(e.request);
        })
    );
});

额外注意事项

  1. Vite生产构建路径:开发环境Vite使用源文件路径,但生产环境会打包到dist目录,资源路径会变化。建议使用workbox-vite插件自动生成缓存清单,避免手动维护路径错误。
  2. 跨域资源处理:对于Google Fonts这类跨域资源,确保资源返回Access-Control-Allow-Origin头,否则无法缓存。可以直接缓存CSS中引用的具体字体文件URL。
  3. 缓存版本管理:每次更新资源时,修改staticCacheName的版本号(比如site-static-v2),确保SW触发更新并清理旧缓存。
  4. 调试技巧:在Chrome开发者工具的Application > Cache Storage中查看缓存资源,确认是否成功缓存;在Service Workers面板查看SW状态和日志。

内容的提问来源于stack exchange,提问作者ipang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:00:12