线性进度条在文件上传时卡在50%不动怎么办?

公孙凡敬 阅读 54

我用axios实现文件上传时,线性进度条显示到50%就卡住不动了,明明文件还在传输。代码里监听了onUploadProgress事件,用progress.value = event.progress更新状态,但实际界面只走一半就不动了,控制台也没报错。

尝试过手动console.log发现event.progress确实停在0.5,后端返回的响应头有设置Content-Length,上传大文件时明显能看到网络请求在持续传输,但前端进度条就是不更新。是不是哪里没处理好事件流?


const upload = (file) => {
  const config = { onUploadProgress: (event) => {
    const progress = (event.loaded / event.total);
    console.log(progress); // 输出到0.5后不再变化
    emit('update:progress', progress);
  }};
  return axios.post('/upload', file, config);
};
我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
技术姝贝
遇到这个问题我也踩过坑,可能是 event.loaded / event.total 的精度丢失导致的。特别是当文件特别大时,浏览器的 progress 事件可能不会均匀触发,尤其是在中间阶段,会出现长时间没有更新的情况。

你可以试试对 event.loadedevent.total 做一个四舍五入,或者保留小数点后几位,避免因为微小的浮点变化导致视图不更新。另外,还可以加入一个“强制刷新”的机制,比如每次计算出来的 progress 变化超过一定阈值(比如 0.5%)时才更新状态,避免卡住的感觉。

修改后的代码如下:

const upload = (file) => {
const config = {
onUploadProgress: (event) => {
const progress = Math.round((event.loaded / event.total) * 100) / 100; // 保留两位小数后再除回去
console.log(progress); // 应该能正常输出到1
emit('update:progress', progress);
}
};
return axios.post('/upload', file, config);
};


如果你发现还是卡顿,可以再进一步优化:

let lastProgress = 0;
const upload = (file) => {
const config = {
onUploadProgress: (event) => {
const progress = Math.round((event.loaded / event.total) * 100) / 100;
if (progress !== lastProgress && Math.abs(progress - lastProgress) > 0.005) {
lastProgress = progress;
emit('update:progress', progress);
}
}
};
return axios.post('/upload', file, config);
};


这样处理之后,进度条应该就能顺畅走完了,希望能帮到你。
点赞 1
2026-02-04 11:35