接到一个需求,要求获取web页面的网速,遂查资料进行了解了一番,总结如下:
普通h5页面也是有api的,例如判断是否有网络 的时间onLine和onoffline(更多事件详情);还有就是navigator.connection获取网络状况 API,兼容性有问题,现在可以使用的浏览器不是太多。
测试结论:
- navigator.connectionAPI不支持:
iphone(微信、微博、UC、QQ浏览器、百度浏览器)安卓(QQ浏览器)
- 支持navigator.connection但不能获取到具体网络type:
安卓(百度浏览器)
- 支持navigator.connection且可获取到type(大多数):
- 安卓(UC、微信、微博)
- 由于测试手机有限,并未覆盖到安卓各种版本与机型,若有错误还请提出
- 暂认为安卓UC、微博支持较好
- 微信在安卓和ios另有可以获取的方式
微信开发
微信中提供了很全面的api,除了小程序的api还有WeixinJSBridge。
// 页面开发 & 小程序开发
wx.getNetworkType({
success: res => {
var networkType = res.networkType; // 返回网络类型2g,3g,4g,wifi
}
})
————————————————
第一种方法
// 借助img.onload测算网速
// 好处:没有跨域问题
// 坏处:要自己测文件大小并提供参数fileSize,且文件必须为图片,文件大小不能灵活控制
function getSpeedWithImg(imgUrl, fileSize) {
return new Promise((resolve, reject) => {
let start = null;
let end = null;
let img = document.createElement('img');
start = new Date().getTime();
img.onload = function (e) {
end = new Date().getTime();
const speed = fileSize * 1000 / (end - start)
resolve(speed);
}
img.src = imgUrl;
}).catch(err => { throw err });
}
第二种方法
// 通过Ajax测算网速
// 好处: 不用提供文件大小参数,测试的文件不一定要是图片,且数据量能灵活控制
// 坏处:跨域
function getSpeedWithAjax(url) {
return new Promise((resolve, reject) => {
let start = null;
let end = null;
start = new Date().getTime();
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
end = new Date().getTime();
const size = xhr.getResponseHeader('Content-Length') / 1024;
const speed = size * 1000 / (end - start)
resolve(speed);
}
}
xhr.open('GET', url);
xhr.send();
}).catch(err => { throw err });
}
第三种方法
// 通过navigator.connection.downlink读取网速
// 优点:1.这是一个同步方法而不是异步方法 2.不需要任何参数
// 缺点:1.兼容性很有问题,2.带宽查询不是实时的,具有分钟级别的时间间隔
function getSpeedWithDnlink() {
// downlink测算网速
const connection = window.navigator.connection;
if (connection && connection.downlink) {
return connection.downlink * 1024 / 8;
}
}
三种结合起来的方法
// 先尝试采用downlink测速,否则多次AJAX测速并求平均值
function getNetSpeed(url, times) {
// downlink测算网速
const connection = window.navigator.connection;
if (connection && connection.downlink) {
return connection.downlink * 1024 / 8;
}
// 多次测速求平均值
const arr = [];
for (let i = 0; i < times; i++) {
arr.push(getSpeedWithAjax(url));
}
return Promise.all(arr).then(speeds => {
// debugger;
let sum = 0;
speeds.forEach(speed => {
sum += speed;
});
return sum / times;
})
}
附:navigator.connection获取网络状况 API的一些字段
bluetooth
蓝牙连接
cellular
A cellular connection (e.g., EDGE, HSPA, LTE, etc.).
ethernet
以太网链接
none
No network connection.
没有网络链接.等同于 navigator.onLine === false
mixed
用户代理用的多个链接类型
other
链接类型未知
unknown
用户代理建立了链接,但是不能够或者不愿意确定潜在的网络连接类型
wifi
wifi连接
wimax
wifimax连接
以上的链接类型都可以通过ConnectionType枚举