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

React中通过Service Worker检测需VPN的API端点是否可达

检测VPN专属API可达性并触发离线页面

客户端定时检测方案

在React应用里通过定时检测目标API的可达性,直接控制离线页面的显示:

  1. 定义检测函数,用HEAD请求+超时机制快速判断API状态:
const checkApiReachability = async () => {
  try {
    const response = await fetch('/your-vpn-only-status-api', {
      method: 'HEAD', // 仅请求响应头,减少数据传输
      signal: AbortSignal.timeout(3000) // 3秒超时,避免长时间等待
    });
    return response.ok;
  } catch (err) {
    // 超时或请求失败都判定为不可达
    return false;
  }
};
  1. 在组件中加入状态管理与定时检测逻辑:
import { useState, useEffect } from 'react';
import OfflinePage from './OfflinePage';

function App() {
  const [isApiReachable, setIsApiReachable] = useState(true);

  useEffect(() => {
    // 初始检测
    checkApiReachability().then(setIsApiReachable);

    // 每10秒检测一次,可根据需求调整间隔
    const interval = setInterval(async () => {
      const reachable = await checkApiReachability();
      setIsApiReachable(reachable);
    }, 10000);

    return () => clearInterval(interval);
  }, []);

  // 如果API不可达,直接渲染离线页面
  if (!isApiReachable) {
    return <OfflinePage />;
  }

  return (
    // 你的正常应用内容
    <div className="App">...</div>
  );
}

export default App;

Service Worker 拦截与通知方案

通过Service Worker在请求层面检测API状态,并主动通知客户端切换离线页面:

  1. 修改Service Worker的fetch事件处理,针对目标API做拦截:
self.addEventListener('fetch', (event) => {
  // 匹配需要VPN访问的API路径
  if (event.request.url.includes('/your-vpn-only-status-api')) {
    event.respondWith(
      fetch(event.request)
        .then(response => {
          if (!response.ok) throw new Error('API响应异常');
          return response;
        })
        .catch(() => {
          // API不可达时返回缓存的离线页面
          return caches.match('/offline.html');
        })
    );
  } else {
    // 保留原有离线缓存逻辑
    event.respondWith(
      fetch(event.request)
        .catch(() => caches.match('/offline.html'))
    );
  }
});
  1. 在Service Worker中定期检测API状态,通过postMessage通知客户端:
// Service Worker内部定时检测
setInterval(async () => {
  let isReachable = false;
  try {
    const response = await fetch('/your-vpn-only-status-api', {
      method: 'HEAD',
      signal: AbortSignal.timeout(3000)
    });
    isReachable = response.ok;
  } catch {}

  // 通知所有活跃客户端
  self.clients.matchAll().then(clients => {
    clients.forEach(client => {
      client.postMessage({
        type: 'API_REACHABILITY_STATUS',
        status: isReachable
      });
    });
  });
}, 10000);
  1. 客户端监听Service Worker的消息,更新状态:
// React组件中加入监听
useEffect(() => {
  if ('serviceWorker' in navigator) {
    const handleMessage = (event) => {
      if (event.data.type === 'API_REACHABILITY_STATUS') {
        setIsApiReachable(event.data.status);
      }
    };

    navigator.serviceWorker.addEventListener('message', handleMessage);
    return () => {
      navigator.serviceWorker.removeEventListener('message', handleMessage);
    };
  }
}, []);

关键注意点

  • 优先使用HEAD请求,相比GET能减少数据传输,提升检测效率
  • 设置合理的超时时间(2-5秒),避免用户感知到明显延迟
  • 定时检测的间隔不要过短(建议10-30秒),防止过多请求浪费资源
  • 确保离线页面已被Service Worker预缓存,保证API不可达时能正常加载

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:45:39