js怎樣檢測用戶是否在線 實時監測用戶網絡狀態變化

檢測用戶在線狀態的核心方法是使用 navigator.online 屬性和 online/offline 事件,1. 初始加載時通過 navigator.online 檢測網絡狀態;2. 使用 online 和 offline 事件監聽網絡變化;3. 結合心跳檢測提升準確性,防止誤判;4. 使用防抖或延遲提示避免頻繁切換帶來的不良體驗;5. 在 react 或 vue 等框架中可通過生命周期或 hook 集成上述邏輯;6. 可選使用 network information api 獲取更詳細網絡信息,但兼容性有限。

js怎樣檢測用戶是否在線 實時監測用戶網絡狀態變化

檢測用戶是否在線,實際上就是在前端監測用戶的網絡連接狀態。這事兒挺重要的,尤其是在WebApp里,用戶體驗直接受影響。

js怎樣檢測用戶是否在線 實時監測用戶網絡狀態變化

解決方案

核心思路就是利用瀏覽器提供的 navigator.onLine 屬性和 online/offline 事件。navigator.onLine 告訴你當前瀏覽器是否認為自己在線,online 和 offline 事件分別在網絡狀態改變時觸發。

js怎樣檢測用戶是否在線 實時監測用戶網絡狀態變化

  1. 初始狀態檢測:

    js怎樣檢測用戶是否在線 實時監測用戶網絡狀態變化

    頁面加載時,先檢查一次 navigator.onLine,根據返回值顯示不同的提示信息。

    if (navigator.onLine) {   console.log("用戶在線");   // 可以加載在線內容 } else {   console.log("用戶離線");   // 顯示離線提示 }
  2. 監聽 online 和 offline 事件:

    這兩個事件分別在網絡連接恢復和斷開時觸發。

    window.addEventListener('online',  function(e) {   console.log("網絡已連接");   // 重新加載數據,或者顯示在線提示 });  window.addEventListener('offline', function(e) {   console.log("網絡已斷開");   // 顯示離線提示,保存未發送的數據 });
  3. 更完善的方案:心跳檢測

    navigator.onLine 有時候不太靠譜,比如用戶連接了WiFi但無法訪問外網,它仍然會返回 true。所以,可以結合心跳檢測。

    定期向服務器發送請求,如果請求失敗,就認為用戶離線。

    function heartbeat() {   fetch('/api/heartbeat') // 假設服務器有一個心跳接口     .then(response => {       if (!response.ok) {         throw new Error('Network response was not ok');       }       // console.log("心跳檢測成功");     })     .catch(error => {       console.log("心跳檢測失敗,用戶可能離線", error);       // 處理離線邏輯     })     .finally(() => {       setTimeout(heartbeat, 5000); // 每5秒檢測一次     }); }  heartbeat();

    服務器端的心跳接口,只需要簡單地返回一個 200 OK 即可。

如何處理網絡不穩定情況,避免頻繁切換在線/離線狀態?

這個問題挺實際的。如果網絡不穩定,online 和 offline 事件會頻繁觸發,導致用戶體驗很差。

  1. 防抖 (Debounce):

    使用防抖函數,只有在一段時間內網絡狀態沒有變化時,才執行相應的操作。

    function debounce(func, delay) {   let timeout;   return function(...args) {     const context = this;     clearTimeout(timeout);     timeout = setTimeout(() => func.apply(context, args), delay);   }; }  const handleOnline = debounce(() => {   console.log("網絡已連接 (防抖)");   // 重新加載數據 }, 1000); // 1秒延遲  const handleOffline = debounce(() => {   console.log("網絡已斷開 (防抖)");   // 顯示離線提示 }, 1000);  window.addEventListener('online',  handleOnline); window.addEventListener('offline', handleOffline);
  2. 延遲提示:

    不要立即顯示離線提示,而是等待一段時間,如果網絡仍然斷開,再顯示提示。

    let offlineTimeout;  window.addEventListener('offline', function(e) {   offlineTimeout = setTimeout(() => {     console.log("網絡已斷開 (延遲提示)");     // 顯示離線提示   }, 3000); // 3秒延遲 });  window.addEventListener('online', function(e) {   clearTimeout(offlineTimeout); // 清除延遲提示   console.log("網絡已連接 (延遲提示)");   // 重新加載數據 });

如何在React或vue等框架中使用這些技術?

其實思路是一樣的,只是需要在框架的生命周期函數或者hooks里使用。

React:

import React, { useState, useEffect } from 'react';  function NetworkStatus() {   const [isOnline, setIsOnline] = useState(navigator.onLine);    useEffect(() => {     const handleOnline = () => setIsOnline(true);     const handleOffline = () => setIsOnline(false);      window.addEventListener('online', handleOnline);     window.addEventListener('offline', handleOffline);      return () => {       window.removeEventListener('online', handleOnline);       window.removeEventListener('offline', handleOffline);     };   }, []);    return (     <div>       {isOnline ? '在線' : '離線'}     </div>   ); }  export default NetworkStatus;

Vue (Composition API):

<template>   <div>     {{ isOnline ? '在線' : '離線' }}   </div> </template>  <script> import { ref, onMounted, onUnmounted } from 'vue';  export default {   setup() {     const isOnline = ref(navigator.onLine);      const handleOnline = () => isOnline.value = true;     const handleOffline = () => isOnline.value = false;      onMounted(() => {       window.addEventListener('online', handleOnline);       window.addEventListener('offline', handleOffline);     });      onUnmounted(() => {       window.removeEventListener('online', handleOnline);       window.removeEventListener('offline', handleOffline);     });      return {       isOnline     };   } } </script>

心跳檢測也類似,只是需要在 useEffect 或 onMounted 里啟動定時器。

除了 navigator.onLine 和 online/offline 事件,還有其他更高級的API可以用來檢測網絡狀態嗎?

有,但兼容性可能不太好,而且實際使用場景不多。

  1. Network Information API:

    這個API提供了更詳細的網絡信息,比如連接類型(WiFi, 4G, etc.)和預估的帶寬。

    if ('connection' in navigator) {   const connection = navigator.connection;   console.log("連接類型:", connection.effectiveType);   console.log("下行速度:", connection.downlink); }

    但這個API的兼容性不是很好,而且很多瀏覽器已經廢棄了一些屬性。

  2. Service Worker 的 background Sync API:

    這個API可以在網絡恢復時自動同步數據。雖然不是直接用來檢測網絡狀態,但可以用來處理離線場景。

總的來說,navigator.onLine 和 online/offline 事件已經足夠滿足大部分需求。結合心跳檢測和防抖/延遲提示,可以提供比較好的用戶體驗。

? 版權聲明
THE END
喜歡就支持一下吧
點贊5 分享