Javascript网络状态获取与监听方案

294 阅读3分钟

1. 需求概述

web页面在很多场景下需要获取当前网络状态做一些对应的操作。如:

  • 网络慢的时候加载较小的资源,反之加载高清资源

  • 切换网络的时候给用户一些提示

下面给出两种获取网络状态的解决方案

2. 方案一(Network Information API)

2.1 获取和监听网络状态

2.1.1 主要用的是navigator的connection属性,如下:

downlink估算的下行速度/带宽,单位Mbps
effectiveType当前的网络连接类型,可枚举值:slow-2g、2g、3g、4g使用最近观察到的往返时间和下行链路值的组合来确定的。
onchange回调函数,在网络状态发生改变后执行
rtt估算的往返时间,单位ms四舍五入到最接近的25毫秒的倍数
saveData是否打开数据保护模式

2.1.2 获取和监听网络状态的改变

const onConnectionChange = () => {
    const { downlink, effectiveType, rtt, saveData } = navigator.connection;
    console.log(`估算的下行速度/带宽:${downlink}Mb/s`);
    console.log(`有效的网络连接类型:${effectiveType}`);
    console.log(`估算的往返时间:${rtt}ms`);
    console.log(`打开/请求数据保护模式:${saveData}`);
}

navigator.connection.addEventListener('change', onConnectionChange);

用浏览器的开发者工具的network模拟网络切换测试效果,如下:

通过navigator.connection可以判断出onlinefast 3gslow 3g,和offline,这四种状态下的effectiveType分别为4g,3g,2g,4g(rtt,downlink均为0)

rtt、downlinkeffectiveType更加具象且更能反映当前网络的真实情况;

网络状况rtt(ms)downlink(Mbit/s)
online1002.2
fast 3g6001.55
slow 3g21500.4
offline00

2.2 获取和监听网络连接、断开状态

  • 通过navigator.connection中的属性downlink === 0Mb/s 且 rtt === 0ms时作为网络断开状态
  • 通过navigator.onLine获取(无法及时获取真实网络连接状态)
// 上线(连网)监听:网络连接上时会触发online事件
window.addEventListener('online', () => {
    console.log(navigator.onLine);
})

// 下线(断网)监听:网络连接断开时会触发offline事件
window.addEventListener('offline', () => {
    console.log(navigator.onLine);
})

2.3 判断网络是否可用

2.2中,只是使用浏览器自身的能力来简单判断网络是否可用;对于局域网中是否真的可以连接网络,需要真实的发起一次网络请求,通过请求结果来判断。

以下是一个使用navigator.onLine和主动发起网络请求的方式,判断网络是否正常的函数的示例。这个函数首先会检查navigator.onLine的值,如果这个值为false,那么函数会立即返回网络不可用。如果这个值为true,函数会进一步发起一个网络请求以验证网络是否真的可用。

const checkNetworkStatus = (url = 'https://www.baidu.com') => {
  return (
    new Promise() <boolean > ((resolve) => {
      if (!navigator.onLine) {
        resolve(false);
      } else {
         fetch(url, { mode: 'no-cors' })
          .then(() => resolve(true))
          .catch((error) => resolve(false))
      }
    })
  );
}

3. 方案二

做一个通用的测速接口,这里直接在服务器端放置一个5Mb大小的图片文件,前端fetch图片地址:

  • 请求从发起到响应的时间差作为延迟;
  • 请求从发起到等待输出文件流的时间差作为请求时间,结合文件流大小计算出下行速度/带宽;

注意:这里要用图片文件,不能用文本文件,因为一般服务端对文本内容会压缩后传输,但实际上拿到的文件内存大小不变,导致计算带宽值不准确。

4. 浏览器兼容性

Chrome 61及以上版本支持,Edge 79及以上版本支持,IE、Safari浏览器不支持,在不支持的浏览器或版本中,可以降级使用方案二替代。