悠悠楠杉
如何用JavaScript实时检测网络状态?5种实战方案详解
本文深度解析JavaScript检测网络状态的5种技术方案,涵盖基础API、事件监听、轮询策略及混合检测方案,提供可直接落地的代码示例和异常处理技巧。
一、为什么需要网络状态检测?
当用户使用Web应用时,网络波动可能导致:
- 表单提交失败
- 实时数据中断
- 资源加载超时
通过前端主动检测网络状态,我们可以:
1. 展示友好离线提示
2. 自动重试失败请求
3. 保存本地数据待恢复后同步
二、基础检测方案
1. navigator.onLine API
javascript
function checkBasicNetwork() {
return navigator.onLine ? '在线' : '离线';
}
特点:
- 立即返回布尔值
- 仅能识别物理连接状态
- 存在浏览器兼容性差异
2. 在线/离线事件监听
javascript
window.addEventListener('online', () => {
console.log('网络恢复');
});
window.addEventListener('offline', () => {
console.warn('网络断开');
});
最佳实践:
- 结合状态栏组件显示
- 重连后自动同步数据
三、高级检测方案
3. Fetch API轮询检测
javascript
let isActualOnline = true;
async function checkNetworkWithFetch() {
try {
await fetch('https://httpbin.org/get', {
method: 'HEAD',
cache: 'no-store',
timeout: 5000
});
if (!isActualOnline) {
console.log('实际网络恢复');
isActualOnline = true;
}
} catch {
if (isActualOnline) {
console.warn('实际网络断开');
isActualOnline = false;
}
}
}
// 每30秒检测一次
setInterval(checkNetworkWithFetch, 30000);
优势:
- 能检测实际网络可达性
- 可自定义超时时间
4. WebSocket心跳检测
javascript
let socket = new WebSocket('wss://echo.websocket.org');
let heartbeatInterval;
socket.onopen = () => {
heartbeatInterval = setInterval(() => {
socket.send('HEARTBEAT');
}, 15000);
};
socket.onclose = () => {
clearInterval(heartbeatInterval);
console.error('连接异常断开');
};
适用场景:
- 实时通信应用
- 需要低延迟检测
四、混合检测最佳实践
javascript
class NetworkMonitor {
constructor() {
this.isOnline = navigator.onLine;
this.bindEvents();
this.startPolling();
}
bindEvents() {
window.addEventListener('online', this.handleOnline);
window.addEventListener('offline', this.handleOffline);
}
startPolling() {
setInterval(async () => {
try {
await this.checkWithFetch();
} catch (error) {
this.handleDisconnect();
}
}, 30000);
}
async checkWithFetch() {
const response = await fetch('/network-test', {
method: 'HEAD',
timeout: 3000
});
return response.ok;
}
}
五、特殊场景处理
1. 弱网环境检测
javascript
const connection = navigator.connection || navigator.mozConnection;
if (connection) {
console.log(`网络类型: ${connection.type}`);
console.log(`下行速度: ${connection.downlink}Mb/s`);
}
2. 服务端状态检测
javascript
async function checkServerStatus() {
const start = performance.now();
try {
await fetch('/health-check');
const latency = performance.now() - start;
return { status: 'healthy', latency };
} catch {
return { status: 'down' };
}
}
六、实用技巧
- 指数退避重试:网络恢复后逐步增加重试间隔
- 状态持久化:使用localStorage记录最后在线状态
- UI响应优化:通过CSS动画平滑过渡网络状态变化
javascript
// 指数退避实现
async function fetchWithRetry(url, retries = 3) {
try {
return await fetch(url);
} catch (err) {
if (retries <= 0) throw err;
await new Promise(r => setTimeout(r, 1000 * (4 - retries)));
return fetchWithRetry(url, retries - 1);
}
}
掌握这些技术后,你可以为不同业务场景选择合适的网络检测方案,显著提升应用健壮性。记住:没有完美的单一方案,组合策略往往能获得最佳效果。