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

如何在渐进式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;
  }
}

三、结合登录场景的完整逻辑

在线状态流程

  1. 确认在线且后端可达后,通过API完成用户认证/授权
  2. 若用户勾选「设备记住」,将加密后的认证凭证存储在localStorage或IndexedDB中

离线状态流程

  1. 读取本地存储的凭证
    • 存在有效未过期凭证:允许访问离线内容
    • 无凭证/凭证过期:提示用户需在线登录并勾选记住功能

代码示例:

// 在线认证逻辑
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:32:48