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

网站无故缓存问题修复及Service Worker优化方案

问题解决与Service Worker优化方案

一、修复当前缓存问题

1. 调整Express静态文件缓存头

你的express.static默认会给静态资源设置Cache-Control头,可能和Cloudflare的缓存策略冲突,导致旧资源被持久缓存。修改托管代码,强制禁用浏览器缓存并开启ETag校验:

app.use("/path", express.static(path, {
  maxAge: 0, // 禁止浏览器本地缓存
  etag: true, // 开启ETag,让Cloudflare能校验资源是否更新
  lastModified: true // 配合Last-Modified头做缓存有效性校验
}));

2. 修正Cloudflare缓存配置

  • 全量清除缓存:执行「Purge Everything」操作,确保Cloudflare所有节点的旧缓存完全清除,不要仅清理单个文件
  • 细分缓存规则:
    • 对HTML文件设置「缓存级别:忽略查询字符串」+「浏览器缓存TTL:0」,避免HTML被长期缓存
    • 对带打包哈希的JS/CSS/图片等静态资源,设置「缓存级别:标准」+「浏览器缓存TTL:1年」,利用文件名哈希自动触发更新,同时最大化缓存效率
    • 检查是否存在Page Rules覆盖了默认缓存策略,比如某些路径设置了「缓存一切」导致旧资源无法更新

3. 临时强制客户端刷新

对于已访问过站点的用户,可在HTML头部添加脚本,检测资源版本差异时自动强制刷新:

<script>
  // 替换{{assetVersion}}为实际的打包版本号(比如React打包后生成的哈希)
  if (localStorage.getItem('assetVersion') !== '{{assetVersion}}') {
    localStorage.setItem('assetVersion', '{{assetVersion}}');
    window.location.reload(true); // 强制从服务器拉取最新内容
  }
</script>

二、Service Worker优化方案

1. 核心优化点

(1)动态获取缓存资源

不要手动维护缓存URL列表,改用React打包生成的asset-manifest.json自动同步需要缓存的资源:

const cacheVersion = 3;
const cacheName = `cache-${cacheVersion}`;
const manifestUrl = '/asset-manifest.json';

self.addEventListener('install', event => {
  event.waitUntil(
    fetch(manifestUrl)
      .then(res => res.json())
      .then(manifest => {
        const assets = Object.values(manifest.files);
        return caches.open(cacheName).then(cache => cache.addAll(assets));
      })
  );
});

(2)分类型缓存策略

针对不同资源类型使用适配策略,平衡更新及时性与加载速度:

self.addEventListener('fetch', event => {
  const request = event.request;
  
  // HTML文件:网络优先,确保用户看到最新内容,缓存仅作离线备用
  if (request.mode === 'navigate' || request.destination === 'document') {
    event.respondWith(
      fetch(request)
        .then(networkRes => {
          caches.open(cacheName).then(cache => cache.put(request, networkRes.clone()));
          return networkRes;
        })
        .catch(() => caches.match(request))
    );
    return;
  }

  // 静态资源:缓存优先,后台静默更新缓存
  if (request.method === 'GET' && !request.url.includes('/api/')) {
    event.respondWith(
      caches.match(request)
        .then(cacheRes => {
          // 后台请求更新缓存,不影响当前页面加载
          const updatePromise = fetch(request).then(networkRes => {
            caches.open(cacheName).then(cache => cache.put(request, networkRes.clone()));
            return networkRes;
          });
          return cacheRes || updatePromise;
        })
    );
    return;
  }

  // 其他请求(API、POST等)直接走网络
  event.respondWith(fetch(request));
});

(3)自动通知用户更新

当Service Worker更新完成后,主动通知用户刷新页面,确保新缓存立即生效:

self.addEventListener('activate', event => {
  event.waitUntil(
    Promise.all([
      // 删除所有旧版本缓存
      caches.keys().then(cacheNames => {
        return Promise.all(
          cacheNames.filter(cache => cache !== cacheName).map(cache => caches.delete(cache))
        );
      }),
      // 立即接管所有打开的客户端页面
      self.clients.claim(),
      // 向所有客户端发送更新通知
      self.clients.matchAll().then(clients => {
        clients.forEach(client => {
          client.postMessage({ type: 'SW_UPDATED' });
        });
      })
    ])
  );
});

// 前端页面监听更新通知
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.addEventListener('message', event => {
    if (event.data.type === 'SW_UPDATED') {
      if (confirm('站点已更新,是否刷新页面获取最新内容?')) {
        window.location.reload();
      }
    }
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:31:34