最可靠方式是用 xmlhttprequest 手动提交并监听 upload.onprogress,因 fetch 尚不支持上传进度;需阻止表单默认提交、用 formdata 收集数据、不手动设 content-type、校验 lengthcomputable 防 nan、上传完成设 progress.value=100。

用 XMLHttpRequest 监听上传进度最可靠
浏览器原生表单提交(submit)不暴露上传过程,没法做进度条。必须改用 XMLHttpRequest 或 fetch 手动发请求,才能监听 upload.onprogress。现代项目推荐用 XMLHttpRequest,因为 fetch 目前仍不支持上传进度事件(UploadProgress 是草案,Chrome/Firefox 都没实现)。
常见错误是直接对 form.submit() 绑定 onprogress——这完全无效,事件根本不会触发。
- 先
event.preventDefault()阻止默认提交 - 用
new FormData(form)收集字段(支持文件、文本、多选等) - 创建
XMLHttpRequest,监听upload.onprogress更新<progress></progress>元素的value - 注意:
onprogress只在上传阶段触发,不是整个请求生命周期
FormData 传文件时要避免手动设 Content-Type
如果用 XMLHttpRequest 发送 FormData,千万别手动设置 Content-Type 头。浏览器会自动加上带随机 boundary 的 multipart/form-data,手动覆盖会导致后端收不到文件(PHP 的 $_FILES 为空,Node.js 的 multer 报错 Unexpected end of form)。
正确写法是让浏览器自动生成头:
xhr.open('POST', '/upload');
// ❌ 错误:xhr.setRequestHeader('Content-Type', 'multipart/form-data');
// ✅ 正确:什么都不设,让浏览器处理
xhr.send(formData);
- 如果需要额外参数(如 token),用
formData.append('token', 'xxx')追加,别塞进 headers - 纯 JSON 提交不用进度条,但若混传文件 + JSON 字段,必须用
FormData,不能JSON.stringify
<progress></progress> 元素更新要防 NaN 和重复触发
event.loaded 和 event.total 在小文件或本地测试时可能为 0,直接除会导致 NaN,<progress value="NaN"></progress> 会卡死或显示异常。同时,某些浏览器(如 Safari)会在上传结束前多次触发 onprogress,但 loaded === total 不一定只出现一次。
- 更新前加判断:
if (e.lengthComputable) { progress.value = (e.loaded / e.total) * 100; } - 把
<progress max="100"></progress>写死,不要依赖 JS 设置max - 提交按钮建议在开始上传时
disabled,防止用户连点;成功/失败后再恢复 - 上传完成(
xhr.onload)后记得手动设progress.value = 100,避免因四舍五入差 0.1% 卡在 99%
服务端返回 200 但前端报错?检查响应体格式
进度条能动,但最终 xhr.onload 拿不到数据,或者解析 JSON 失败,大概率是服务端返回了非 JSON 内容(比如 PHP 输出了 warning、Node.js 忘了 res.end()、Nginx 加了额外 header)。此时 xhr.response 可能是 HTML 或空字符串,JSON.parse 就会抛错。
- 用浏览器 DevTools 的 Network 面板看「Response」标签页,确认返回的是纯 JSON(如
{"ok":true}) - 后端务必关掉调试输出(PHP 的
error_reporting(0),Python 的logging关闭) - 前端加兜底:
try { JSON.parse(xhr.response); } catch(e) { console.error('Invalid JSON:', xhr.response); }
进度条本身不解决后端逻辑问题,但它把“卡住”变成了可观察的数值——这恰恰是最容易被忽略的:你看到进度走到 100%,不代表后端已处理完,只代表字节发完了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











