如何使用axios实时获取文件上传传输速度?
基于axios onUploadProgress的实时上传速度实现方案
核心原理
onUploadProgress 回调会返回当前已上传的字节数,我们通过计算相邻两次回调的字节差和时间差,即可换算出当前的瞬时上传速度。如果需要平滑显示,可对最近多次计算的速度取平均值。
完整实现代码
// 初始化状态变量,可根据实际场景放在组件状态/全局状态中 let lastUploadedBytes = 0; let lastRecordTime = Date.now(); let currentSpeed = 0; // 单位:字节/秒 // 上传请求配置 axios.post('/your/upload/interface', formData, { onUploadProgress: (progressEvent) => { const now = Date.now(); // 时间差转成秒单位 const timeDiff = (now - lastRecordTime) / 1000; // 两次回调之间新上传的字节数 const uploadedDiff = progressEvent.loaded - lastUploadedBytes; // 加阈值避免时间差太小导致速度计算异常,最低间隔100ms更新一次 if (timeDiff >= 0.1) { currentSpeed = uploadedDiff / timeDiff; // 转成易读的单位展示 let displaySpeed; if (currentSpeed >= 1024 * 1024) { displaySpeed = `${(currentSpeed / (1024 * 1024)).toFixed(2)} MB/s`; } else if (currentSpeed >= 1024) { displaySpeed = `${(currentSpeed / 1024).toFixed(2)} KB/s`; } else { displaySpeed = `${currentSpeed.toFixed(0)} B/s`; } // 此处将displaySpeed更新到界面展示即可 console.log('当前上传速度:', displaySpeed); // 更新记录值 lastUploadedBytes = progressEvent.loaded; lastRecordTime = now; } // 同步更新进度条(可选) if (progressEvent.total) { const uploadProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total); console.log('上传进度:', uploadProgress + '%'); } } }).then(res => { // 上传完成后重置状态,避免下次上传计算出错 lastUploadedBytes = 0; lastRecordTime = Date.now(); currentSpeed = 0; })
可选优化点
- 若要实现每秒固定刷新一次速度展示,可单独开启一个每秒执行的定时器,统一读取
currentSpeed值渲染界面,避免频繁触发界面更新导致跳变 - 可维护一个长度为3~5的速度缓存数组,每次计算新速度后推入数组、移除最早的数值,取数组平均值作为展示速度,显示效果更平滑,和Google Drive的速度展示体验一致
- 小文件上传时因上传周期过短,速度计算误差较大属于正常现象,可针对小于1M的文件单独做展示兼容
内容的提问来源于stack exchange,提问作者Rahul Ahire
相关产品推荐
相关产品推荐

