React中通过Service Worker检测需VPN的API端点是否可达
检测VPN专属API可达性并触发离线页面
客户端定时检测方案
在React应用里通过定时检测目标API的可达性,直接控制离线页面的显示:
- 定义检测函数,用
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; } };
- 在组件中加入状态管理与定时检测逻辑:
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状态,并主动通知客户端切换离线页面:
- 修改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')) ); } });
- 在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);
- 客户端监听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
相关产品推荐
相关产品推荐

