分片上传时如何正确显示上传进度条?

玉萱 阅读 47

我在做文件分片上传,每个分片用 axios 发送,但进度条总是跳变不平滑,不知道该怎么合并各分片的进度来更新整体进度?

试过在每个请求的 onUploadProgress 里累加 progress,但总大小算不准,导致进度条要么卡住要么直接到100%。下面是我用来显示进度条的样式:

.upload-progress {
  width: 100%;
  height: 8px;
  background: #eee;
  border-radius: 4px;
  overflow: hidden;
}
.upload-progress .bar {
  height: 100%;
  background: #4caf50;
  width: 0%;
  transition: width 0.2s ease;
}

有没有人遇到过类似问题?怎么准确计算总进度啊?

我来解答 赞 10 收藏
二维码
手机扫码查看
1 条解答
爱巧 Dev
分片上传进度计算的核心问题是:你需要记录已完成分片的总字节数,然后加上当前正在上传分片的已传字节,才是真正的整体进度。

直接上代码:

let uploadedSize = 0; // 已完成上传的分片总大小
const chunkSize = 1024 * 1024; // 每个分片1MB
const totalChunks = Math.ceil(file.size / chunkSize);

async function uploadFile() {
for (let i = 0; i < totalChunks; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);

await uploadChunk(chunk, (progressEvent) => {
// 当前分片已上传的字节
const currentChunkLoaded = progressEvent.loaded;
// 整体进度 = (已完成分片 + 当前分片已传) / 总大小
const totalLoaded = uploadedSize + currentChunkLoaded;
const percent = Math.round((totalLoaded / file.size) * 100);

document.querySelector('.bar').style.width = percent + '%';
});

// 分片上传完成后,累加已上传大小
uploadedSize += (end - start);
}
}

function uploadChunk(chunk, onProgress) {
return new Promise((resolve) => {
const formData = new FormData();
formData.append('file', chunk);

axios.post('/upload', formData, {
onUploadProgress: (progressEvent) => {
onProgress(progressEvent);
}
}).then(resolve);
});
}


几个关键点:

已上传完成的分片大小要单独记录,每次分片传完就累加。计算进度时用 uploadedSize + 当前分片的 loaded,别直接用 progressEvent 的 percent。然后 axios 的 progressEvent.loaded 是当前请求已传的字节数,不是百分比。

如果想并行上传多个分片,思路也差不多,每个分片独立维护自己的进度,最后汇总:

let uploadedSize = 0; // 已完成分片总大小
const chunkProgress = new Array(totalChunks).fill(0); // 各分片当前进度

function updateTotalProgress() {
const currentUploading = chunkProgress.reduce((a, b) => a + b, 0);
const totalLoaded = uploadedSize + currentUploading;
const percent = Math.round((totalLoaded / file.size) * 100);
document.querySelector('.bar').style.width = percent + '%';
}


并行的话进度条跳动会明显一些,因为同时多个在跑,顺序上传最平滑,你自己权衡。
点赞
2026-03-17 19:13