javascript中文件上传进度监听的核心是xmlhttprequest的upload.onprogress事件,配合formdata构造请求体;fetch原生不支持上传进度,axios等库通过封装xhr提供onuploadprogress简化开发;大文件推荐分片上传以提升稳定性与精度。

JavaScript 中用 Ajax 实现文件上传并实时监听进度,核心是使用 XMLHttpRequest 的 upload.onprogress 事件,配合 FormData 构造请求体。现代项目更推荐用 fetch + AbortController 配合 ReadableStream(较新),但进度监听仍需依赖 XMLHttpRequest 或第三方库(如 axios)的封装能力。下面以原生 XMLHttpRequest 为主,给出清晰、可直接运行的实现方案。
1. 使用 XMLHttpRequest + FormData 上传文件并监听进度
这是最稳定、兼容性好、原生支持进度监听的方式。
-
创建 FormData 对象:把
<input type="file">选中的文件 append 进去;可同时传其他字段(如 token、描述) -
新建 xhr 实例:调用
xhr.upload.onprogress监听上传中事件,通过event.loaded和event.total计算百分比 -
注意设置 xhr.responseType(如需要 JSON 响应);发送前设置请求头(
Content-Type通常由浏览器自动设为multipart/form-data,不要手动覆盖)
示例代码:
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function (e) {
const file = e.target.files[0];
if (!file) return;
<p>const formData = new FormData();
formData.append('file', file); // 后端接收字段名通常是 'file'
formData.append('desc', '上传说明'); // 其他字段也支持</p><p>const xhr = new XMLHttpRequest();</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5703" title="deep-java-review"><img
src="https://img.php.cn/upload/skill/000/000/081/179060057413304.jpg" alt="deep-java-review" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5703" title="deep-java-review" class="overflowclass">deep-java-review</a>
<p class="overflowclass">Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...</p>
</div>
<a rel="nofollow" href="/xiazai/skill5703" title="deep-java-review" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><p>// 上传进度监听
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
console.log(<code>上传中:${percent}%</code>);
// 更新页面进度条,例如:document.getElementById('progress').value = percent;
}
};</p><p>// 上传完成
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status </p><p>// 上传出错
xhr.onerror = function () {
console.error('网络错误');
};</p><p>xhr.open('POST', '/api/upload');
xhr.send(formData);
});</p>2. 使用 axios(更简洁,自动处理进度)
axios 内部封装了 XMLHttpRequest,提供更友好的进度回调接口,适合 Vue/React 项目。
- 安装:
npm install axios - 用
onUploadProgress配置项监听上传过程,参数是原生 ProgressEvent - 无需手动构造 FormData,axios 会自动处理;也可传入已构建的 FormData
示例:
import axios from 'axios';
<p>const uploadFile = async (file) => {
const formData = new FormData();
formData.append('file', file);</p><p>try {
const res = await axios.post('/api/upload', formData, {
onUploadProgress: (progressEvent) => {
if (progressEvent.lengthComputable) {
const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
console.log(<code>进度:${percent}%</code>);
// 更新 UI,例如 this.progress = percent;
}
}
});
console.log('上传完成', res.data);
} catch (err) {
console.error('上传失败', err);
}
};</p>3. 注意事项与常见问题
-
后端必须支持文件上传解析(如 Express 用
multer,Koa 用@koa/multer,Spring Boot 用MultipartFile) -
跨域时后端要允许携带凭证:响应头需含
Access-Control-Allow-Origin(不能为*如果带 cookie)和Access-Control-Allow-Credentials: true - 大文件建议分片上传:单次上传易超时或失败;进度监听仍是按每个分片计算,再汇总
-
移动端 Safari 对 large file 的
onprogress支持不稳定,可降级为“开始/完成”两态提示
4. 补充:fetch 能监听上传进度吗?
原生 fetch 不支持上传进度监听(它没有类似 xhr.upload 的 API)。虽然可通过 ReadableStream 手动分块读取并发送(搭配 AbortController),但需后端配合分片接收,复杂度高,且无法直接获取服务器返回的 total 字节数(因服务端可能压缩/转码)。所以生产环境仍推荐 XMLHttpRequest 或 axios。
不复杂但容易忽略:只要后端正确返回 Content-Length、前端用 xhr 发送 multipart 请求,进度监听就可靠可用。关键在前后端协作,而非某一个“高级 API”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










