如何为特定请求绕过Service Worker?React在线检测问题求助
解决Service Worker导致网络状态检测误判的问题
你的问题出在离线时Service Worker返回了缓存的/hello.png资源(200状态),导致Hook误判为在线。要让这个请求绕过Service Worker,有两种可靠的解决方案:
方案一:直接在Hook的Fetch请求中绕过Service Worker
在fetch调用时添加cache: 'no-store'选项,强制请求直接走网络,不经过Service Worker的缓存逻辑。修改后的Hook代码如下:
import { useEffect, useState } from 'react'; export const useOnline = () => { const [online, setOnline] = useState(true); const checkOnline = async () => { try { // 添加cache: 'no-store'强制绕过缓存和Service Worker const response = await fetch('/hello.png', { cache: 'no-store' }); setOnline(response.ok); } catch { setOnline(false); } }; useEffect(() => { const handleStatusChange = () => { checkOnline(); // 触发事件时重新校验网络,而非直接取反状态 }; checkOnline(); // 初始加载时校验 window.addEventListener('online', handleStatusChange); window.addEventListener('offline', handleStatusChange); return () => { window.removeEventListener('online', handleStatusChange); window.removeEventListener('offline', handleStatusChange); }; }, []); // 空依赖确保只注册一次监听器 return online; };
方案二:在Service Worker中对指定请求放行
修正你原来的Service Worker代码,正确匹配/hello.png请求,并让它直接走网络:
self.addEventListener('fetch', function(event) { // 精确匹配/hello.png的请求 if (event.request.url.endsWith('/hello.png')) { // 直接发起网络请求,不使用Service Worker的缓存 event.respondWith(fetch(event.request)); } // 其他请求保留原有的离线缓存逻辑 });
额外说明
- 你原来的Hook事件监听存在问题:直接取反
online状态会因为闭包捕获旧值导致错误,改为触发时重新调用checkOnline()更可靠,同时浏览器的online/offline事件本身并不完全准确,实际请求校验才是判断网络状态的最优方式。 - 方案一无需修改Service Worker,更轻量化;方案二适合需要在Service Worker层面统一控制的场景,选其一即可。
内容的提问来源于stack exchange,提问作者lele
相关产品推荐
相关产品推荐

