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

React搭配Workbox的Service Worker未缓存所有GET API请求如何解决

缓存问题分析与解决方案

现象原因

出现该现象的核心原因有两点:

  • 当前Service Worker中自定义的fetch事件仅实现了请求失败时回退读取缓存的逻辑,没有编写将请求成功的响应写入缓存的代码,因此默认不会自动存储接口的返回结果。
  • Pokémon API返回的响应头配置了合法的缓存规则(存在max-age等缓存有效字段),浏览器原生HTTP缓存会自动存储该响应,断网时可直接从原生缓存中读取返回;而另外两个随机数据接口的响应头配置了禁止缓存标识(Cache-Control为no-store/no-cache),浏览器原生缓存不会存储,因此断网时无法获取对应内容。

实现方案

要实现所有接口首次请求就缓存最新返回值,可选择以下两种方案,推荐优先使用Workbox内置规则,避免手动处理边界问题:

方案1:使用Workbox路由规则(推荐)

首先删除原有自定义的fetch事件监听代码,在Service Worker末尾新增以下代码即可:

// 匹配所有GET类型的API请求
registerRoute(
  ({ request }) => request.method === 'GET' && request.destination === '',
  // 采用先返回缓存同时后台更新缓存的策略,断网直接返回缓存内容
  new StaleWhileRevalidate({
    cacheName: 'api-cache',
    plugins: [
      new ExpirationPlugin({
        maxAgeSeconds: 7 * 24 * 60 * 60, // 缓存有效期可自定义,这里设为7天
        maxEntries: 100, // 最多缓存100条接口响应,超出自动删除最早使用的缓存
      }),
    ],
  })
);

方案2:修改原生fetch事件逻辑

如果不想使用Workbox规则,直接修改原有fetch事件代码,新增写入缓存的逻辑即可:

self.addEventListener('fetch', function (event) {
  // 仅处理GET请求,避免缓存POST等其他类型请求
  if (event.request.method !== 'GET') return;
  event.respondWith(
    caches.open('api-cache').then(function(cache) {
      return fetch(event.request)
        .then(function(networkResponse) {
          // 请求成功时,克隆一份响应写入缓存
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        })
        .catch(function() {
          // 断网时直接返回缓存中的对应响应
          return cache.match(event.request);
        });
    })
  );
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:39:04