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

如何为特定请求绕过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:45:42