input[type="file"]本身不触发进度事件,因为它仅负责文件选择而不参与上传;进度监听必须绑定在XMLHttpRequest.upload对象上,fetch目前不支持上传进度回调,且需确保服务端正确响应。

为什么 input[type="file"] 本身不触发进度事件
因为原生文件选择控件只负责选文件,不参与上传过程。进度反馈必须绑定在后续的 XMLHttpRequest 或 fetch 请求上,而不是 input 元素本身。常见错误是给 input 绑定 progress 事件——它根本不会触发。
真正能监听上传进度的,只有发起网络请求的对象,且仅限于 XMLHttpRequest(fetch 目前仍不支持上传进度回调)。
- 必须用
XMLHttpRequest.upload对象监听progress、load、error等事件 -
FormData是必备中间层:把input.files[0]append 进去再发送 - 服务端必须正常接收并返回响应,否则前端会卡在
uploading状态或触发error
如何用 XMLHttpRequest 正确监听上传进度
关键不是“怎么显示”,而是“在哪绑、绑谁、怎么算百分比”。下面是最小可靠写法:
const input = document.querySelector('input[type="file"]');
const xhr = new XMLHttpRequest();
<p>input.addEventListener('change', () => {
const file = input.files[0];
if (!file) return;</p><p>xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
console.log(<code>上传中: ${percent}%</code>);
// 更新你的进度条 DOM,例如:progressBar.style.width = <code>${percent}%</code>;
}
});</p><p>xhr.addEventListener('load', () => {
console.log('上传完成');
});</p><p>xhr.addEventListener('error', () => {
console.error('上传失败');
});</p><p>xhr.open('POST', '/upload');
xhr.send(new FormData());
});-
e.lengthComputable必须判断,某些服务器未返回Content-Length时e.total为 0,直接除会导致NaN -
FormData构造时要传入file:const fd = new FormData(); fd.append('file', file); - 不要在
change回调里重复创建xhr实例却不 abort——多次选文件会堆积未完成请求
使用 fetch 能不能实现上传进度
不能。截至 Chrome 125 / Firefox 126 / Safari 17.5,fetch 仍不提供上传进度钩子。尝试监听 ReadableStream 的上传体是徒劳的——浏览器未暴露底层传输流。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
有人用分块上传 + 手动计算已发字节数模拟进度,但需服务端配合分片逻辑,复杂度陡增,且无法反映真实网络传输状态(比如卡在 TCP 重传、服务端处理阻塞)。
- 想用
fetch?只能等未来标准支持UploadStream或signal进度扩展 - 当前生产环境唯一可靠方案仍是
XMLHttpRequest - 注意 IE10+ 支持
xhr.upload,IE9 及以下完全不可用
进度显示容易被忽略的细节
进度条动了≠上传成功,很多 UI 停在 99% 就不动,其实是服务端没返回、超时或 CORS 预检失败。
- 务必监听
xhr.upload.onerror和xhr.onerror——前者是网络层失败(如断网),后者是 HTTP 层失败(如 500) - 服务端响应头必须包含
Access-Control-Allow-Origin,否则load不会触发,进度条卡死 - 大文件上传时,
progress事件可能高频触发(每几十 KB 一次),避免在回调里做 DOM 重排或复杂计算 - 移动端 WebView(尤其旧版 Android)对
xhr.upload支持不稳定,建议加降级提示:“上传中,请勿关闭页面”
进度的本质是客户端对已发出字节的统计,它不保证服务端接收完整、不校验文件内容、也不反映后端处理耗时。真要保障可靠性,得靠上传后的服务端校验 + 前端轮询结果接口。


















