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

AngularJS 1.x离线场景下Service Worker fetch始终返回200求助

解决真实离线时Service Worker fetch不触发catch的问题

我太懂这个坑了!真实断网(WiFi断开/飞行模式)时浏览器总返回200,只有DevTools离线模式才正常,核心原因是浏览器的HTTP缓存优先于Service Worker的fetch逻辑——离线时浏览器直接拿出之前缓存的主页响应,不会让fetch抛出错误,所以你的catch块永远得不到执行机会。

下面是具体的解决思路和代码修改方案:

1. 强制跳过浏览器HTTP缓存(最直接的方案)

Fetch API提供了cache选项,设置为'no-store'可以强制跳过浏览器的HTTP缓存,确保请求真正去尝试访问网络,失败才进入catch。修改你的homeNetworkThenCache函数:

function homeNetworkThenCache(request){
  return fetch(request, { cache: 'no-store' }) // 关键:强制绕过浏览器缓存
    .then(response => {
      // 可选:成功获取后更新缓存里的主页,保证缓存是最新的
      caches.open('your-app-cache').then(cache => {
        cache.put(offlineHomepageUrl, response.clone());
      });
      return response;
    })
    .catch(() => caches.match(offlineHomepageUrl));
}

2. 验证响应有效性(兜底方案)

如果第一种方案还不行,可以在then块里主动检查响应是否真正来自网络,而不是浏览器缓存:

function homeNetworkThenCache(request){
  return fetch(request)
    .then(response => {
      // 两个判断:状态码正常,且不是来自缓存(可根据实际调整)
      if (!response.ok || response.headers.get('age') > 0) {
        // 抛出错误,进入catch逻辑
        throw new Error('Invalid or cached response');
      }
      // 更新缓存
      caches.open('your-app-cache').then(cache => {
        cache.put(offlineHomepageUrl, response.clone());
      });
      return response;
    })
    .catch(() => caches.match(offlineHomepageUrl));
}

这里用response.ok检查状态码是否在200-299区间,用age响应头判断是否来自缓存(如果服务器正确设置的话)。如果后端可以配合,也可以添加自定义响应头比如x-source: network,这样判断更准确。

额外注意事项

  • 确保你的Service Worker已经正确缓存了offlineHomepageUrl对应的资源,可以在Chrome DevTools的Application > Cache Storage里查看。
  • 测试真实离线场景时,建议用隐私窗口,避免浏览器之前的缓存干扰。
  • 如果你是AngularJS单页应用,要确保所有导航请求都被Service Worker拦截,并且离线主页是正确的index.html(因为AngularJS路由是前端路由,刷新时都会请求主页)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:25:27