文件上传进度条百分比卡在0%不动怎么办?

爱学习的令敏 阅读 76

正在做一个文件上传功能,想用XMLHttpRequest实现进度条显示百分比。按照网上的教程写了onprogress监听,但页面上的百分比一直卡在0%不更新,这是为什么呢?

代码结构大概是这样的: xhr.upload.addEventListener('progress', handleProgress),然后在handleProgress里用event.loaded / event.total * 100算百分比。上传确实在进行,但控制台打印的百分比始终是0。

尝试过把计算改成(event.loaded / event.total) * 100,也检查过文件确实大于上传阈值。甚至把进度条的更新写成了setTimeout模拟,但真实数据就是获取不到正确值…


function handleProgress(event) {
  if (event.lengthComputable) {
    const percent = (event.loaded / event.total) * 100;
    console.log('当前进度:', percent.toFixed(0)); // 这里始终输出0
    document.querySelector('.progress-bar').style.width = `${percent}%`;
  }
}
我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
W″利伟
你这个应该是服务器在处理大文件时没及时返回响应头,导致浏览器拿不到total值。试试在后端接口加上 Access-Control-Expose-Headers: Content-Length,确保跨域时能暴露内容长度。

还有种可能是小文件上传太快,还没触发几次progress事件就结束了。加个延迟测试下:
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
console.log('进度', Math.round(percent));
document.querySelector('.progress-bar').style.width = percent + '%';
}
});

应该能用。
点赞 1
2026-02-09 08:08
Mr.翌钊
Mr.翌钊 Lv1
你这个问题挺典型的,event.lengthComputable 如果一直为 false,那肯定是 event.total 拿不到正确值。这种情况大概率是后端没设置响应头 Content-Length 或者文件流处理有问题。

先确认后端是否返回了正确的 Content-Length,如果没返回,前端再怎么折腾也白搭。如果你能控制后端,让后端确保返回这个头信息。

另外,浏览器对小文件的上传可能会优化合并请求,导致进度条显示不准确。你可以试试上传大一点的文件测试一下。

最后,这里给你一个更高效的写法,顺便加个防抖,避免频繁更新 DOM:

let lastPercent = 0;

function handleProgress(event) {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
// 防止重复更新相同的百分比
if (percent > lastPercent) {
lastPercent = percent;
console.log('当前进度:', percent);
document.querySelector('.progress-bar').style.width = ${percent}%;
}
}
}


这样性能更高,DOM 不会频繁重绘。记得检查后端部分哦!
点赞 18
2026-02-01 12:06