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
相关产品推荐
相关产品推荐

