js实现上传进度条
实现上传进度条的方法
XMLHttpRequest 方法
使用 XMLHttpRequest 对象的 upload 属性监听进度事件。XMLHttpRequest 提供了 progress 事件,可以实时获取上传进度。

const xhr = new XMLHttpRequest();
const fileInput = document.getElementById('fileInput');
const progressBar = document.getElementById('progressBar');
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
progressBar.style.width = `${percentComplete}%`;
progressBar.textContent = `${Math.round(percentComplete)}%`;
}
});
xhr.open('POST', '/upload', true);
xhr.send(new FormData(fileInput));
Fetch API 方法
Fetch API 本身不直接支持进度跟踪,但可以通过 ReadableStream 和 TransformStream 实现类似功能。

const fileInput = document.getElementById('fileInput');
const progressBar = document.getElementById('progressBar');
async function uploadWithProgress(file) {
const reader = file.stream().getReader();
let totalUploaded = 0;
const stream = new ReadableStream({
async pull(controller) {
const { done, value } = await reader.read();
if (done) {
controller.close();
return;
}
totalUploaded += value.length;
const percentComplete = (totalUploaded / file.size) * 100;
progressBar.style.width = `${percentComplete}%`;
progressBar.textContent = `${Math.round(percentComplete)}%`;
controller.enqueue(value);
}
});
await fetch('/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/octet-stream' },
body: stream
});
}
fileInput.addEventListener('change', () => {
uploadWithProgress(fileInput.files[0]);
});
Axios 方法
Axios 提供了 onUploadProgress 回调函数,可以方便地跟踪上传进度。
const axios = require('axios');
const fileInput = document.getElementById('fileInput');
const progressBar = document.getElementById('progressBar');
const uploadFile = (file) => {
const formData = new FormData();
formData.append('file', file);
axios.post('/upload', formData, {
onUploadProgress: (progressEvent) => {
const percentComplete = Math.round((progressEvent.loaded * 100) / progressEvent.total);
progressBar.style.width = `${percentComplete}%`;
progressBar.textContent = `${percentComplete}%`;
}
});
};
fileInput.addEventListener('change', () => {
uploadFile(fileInput.files[0]);
});
使用第三方库
一些第三方库如 uppy 或 dropzone 提供了内置的上传进度功能。
const uppy = new Uppy({
restrictions: {
maxFileSize: 1000000,
maxNumberOfFiles: 3,
allowedFileTypes: ['image/*']
}
});
uppy.use(Dashboard, {
inline: true,
target: '#upload-container'
});
uppy.use(XHRUpload, {
endpoint: '/upload',
fieldName: 'file'
});
uppy.on('upload-progress', (file, progress) => {
console.log(file.id, progress.percent);
});
注意事项
- 确保服务器支持分块上传或正确处理上传进度。
- 对于大文件上传,考虑使用分块上传以减少内存占用。
- 跨域请求时,服务器需要配置 CORS 头部以允许进度事件。
以上方法可以根据项目需求和技术栈选择适合的实现方式。






