如何在渐进式Web应用(PWA)中检测用户是否在线?
PWA在线状态检测与登录逻辑实现
一、优化navigator.onLine的使用
navigator.onLine只能判断浏览器是否有网络连接,无法直接确认后端服务可达,需结合事件监听+后端可达性验证:
// 监听网络状态切换事件 window.addEventListener('online', handleNetworkChange); window.addEventListener('offline', handleNetworkChange); function handleNetworkChange() { const isBrowserOnline = navigator.onLine; if (isBrowserOnline) { // 额外验证后端是否可访问 checkBackendReachability().then(isBackendReachable => { isBackendReachable ? handleOnlineAuth() : showBackendUnreachableTip(); }); } else { handleOfflineLogin(); } }
二、基于API请求的超时检测(await实现)
通过轻量API请求+超时判断,精准检测后端服务状态,适合作为navigator.onLine的补充:
async function checkBackendReachability(timeout = 3000) { try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeout); const response = await fetch('/api/ping', { signal: controller.signal, method: 'GET', cache: 'no-store' // 避免缓存,确保实时检测 }); clearTimeout(timeoutId); return response.ok; } catch (err) { // 请求超时/失败,判定为后端不可达 return false; } }
三、结合登录场景的完整逻辑
在线状态流程
- 确认在线且后端可达后,通过API完成用户认证/授权
- 若用户勾选「设备记住」,将加密后的认证凭证存储在
localStorage或IndexedDB中
离线状态流程
- 读取本地存储的凭证
- 存在有效未过期凭证:允许访问离线内容
- 无凭证/凭证过期:提示用户需在线登录并勾选记住功能
代码示例:
// 在线认证逻辑 async function handleOnlineAuth() { try { const authResponse = await fetch('/api/auth', { method: 'POST', credentials: 'include' }); if (authResponse.ok) { const userInfo = await authResponse.json(); // 存储加密后的本地凭证(需用Web Crypto API加密敏感信息) if (userInfo.rememberDevice) { localStorage.setItem('localAuth', JSON.stringify({ userId: userInfo.id, expires: Date.now() + 7 * 24 * 60 * 60 * 1000 // 7天有效期 })); } loadAppContent(); } else { redirectToLogin(); } } catch (err) { // 请求失败,降级到离线逻辑 handleOfflineLogin(); } } // 离线登录逻辑 function handleOfflineLogin() { const localAuth = localStorage.getItem('localAuth'); if (localAuth) { const authData = JSON.parse(localAuth); if (authData.expires > Date.now()) { loadOfflineAppContent(); } else { showTip('本地登录凭证已过期,请在线时重新登录并勾选记住设备'); } } else { showTip('未在线登录并勾选设备记住功能,无法访问内容'); } }
四、关键注意事项
- 敏感信息存储:
localStorage为明文存储,需用Web Crypto API加密后再存储用户凭证 - 离线同步:离线编辑的内容存入
IndexedDB,在线时可通过PWA的Background Sync API实现后台同步 - 兼容性:
navigator.onLine和AbortController支持所有现代浏览器,无需额外兼容处理
内容的提问来源于stack exchange,提问作者Alrampaz
相关产品推荐
相关产品推荐

