javascript监听ajax上传进度最直接方式是使用xmlhttprequest.upload的progress事件,需绑定在xhr.upload上、open后send前,依赖e.lengthcomputable判断是否可计算百分比;axios通过onuploadprogress封装该能力,更简洁;fetch原生不支持上传进度监听。

JavaScript 中监听 Ajax 上传进度并更新 UI,核心是利用 XMLHttpRequest.upload 的 progress 事件。Fetch API 原生不支持上传进度监听,Axios 则封装了 onUploadProgress 钩子,底层仍依赖 XHR。
用 XMLHttpRequest 监听 upload.progress 事件
这是最直接、兼容性最好、且能精确获取已上传字节数(e.loaded)与总大小(e.total)的方式。关键点:
- 必须绑定在
xhr.upload上,不是xhr本身 - 需确保服务端返回
Content-Length头,或浏览器能预估文件总大小(如传入 File 对象时通常可计算) - 事件绑定要在
xhr.open()之后、xhr.send()之前 -
e.lengthComputable为 true 才能安全计算百分比
示例代码:
const xhr = new XMLHttpRequest();
const file = document.getElementById('fileInput').files[0];
const formData = new FormData();
formData.append('file', file);
formData.append('username', 'Tom');
<p>xhr.upload.onprogress = e => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
document.getElementById('progressBar').value = percent;
}
};</p><p>xhr.onload = () => {
if (xhr.status === 200) {
console.log('上传成功');
}
};
xhr.onerror = () => console.error('上传失败');
xhr.ontimeout = () => console.warn('上传超时');
xhr.timeout = 60000;</p><p>xhr.open('POST', '/api/upload', true);
xhr.send(formData);
</p>
用 Axios 封装更简洁的上传进度控制
Axios 提供了开箱即用的 onUploadProgress 配置项,内部自动处理 XHR 实例和事件绑定,写法更语义化:
- 无需手动创建 XHR,避免低层细节干扰
- 支持 Promise 风格链式调用,错误统一走
.catch - 可配合
CancelToken或AbortController实现取消上传
示例:
const formData = new FormData();
formData.append('file', file);
formData.append('desc', '测试文档');
<p>axios.post('/api/upload', formData, {
headers: { 'X-Requested-With': 'XMLHttpRequest' },
onUploadProgress: progressEvent => {
if (progressEvent.lengthComputable) {
const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
updateUI(percent); // 如更新 progress 元素或自定义 div 宽度
}
}
})
.then(res => console.log('响应:', res.data))
.catch(err => console.error('错误:', err.response?.status || err.message));
</p>
更新 UI 的常见方式
进度条 UI 不必复杂,关键是及时、平滑、可重置:
- 用原生
<progress></progress>标签:设置value属性即可,语义清晰、无障碍友好 - 用
div模拟:通过内联style.width控制填充宽度,适合定制样式 - 上传完成或失败后务必重置进度条(如设为 0),避免残留状态误导用户
- 可加文字提示,如“上传中… 65%”,提升信息明确性
例如:
<progress id="uploadProgress" value="0" max="100"></progress><span id="progressText">等待上传</span>
在 onprogress 中同步更新:
document.getElementById('uploadProgress').value = percent;
document.getElementById('progressText').textContent = `上传中… ${percent}%`;
注意 fetch 无法监听上传进度
尽管 Fetch 是现代推荐的网络 API,但它**不提供上传进度回调接口**。即使传入 Blob 或 File,fetch() 也只在请求发起时整体提交数据,无法分片捕获已发送字节数。
若坚持使用 fetch,目前只有两种变通方案:
- 服务端主动推送进度(如 SSE 或 WebSocket),前端轮询或监听事件——增加后端复杂度
- 将大文件切片上传,按每个分片的成功与否估算整体进度——适用于分片上传场景,但非实时上传流
所以,只要需要真实上传进度,应优先选用 XHR 或基于它的 Axios。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











