JavaScript实现文件上传进度条的核心是利用XMLHttpRequest的upload.onprogress事件监听上传过程并实时更新DOM;需在xhr.open后、send前绑定事件,注意CORS配置与后端正确响应。

JavaScript 中实现文件上传进度条,核心是利用 XMLHttpRequest 的 upload.onprogress 事件监听上传过程,并实时更新 DOM 元素(如 <progress> 或自定义 div)的值。现代浏览器也支持 fetch + ReadableStream,但兼容性和易用性目前仍以 XHR 为主。
1. 基础 HTML 结构:准备上传入口和进度容器
需要一个文件输入框、一个触发按钮(可选)、一个进度条元素(推荐使用原生 <progress>),以及可选的文字提示:
<button id="uploadBtn">上传</button>
<progress id="progressBar" value="0" max="100"></progress>
<span id="progressText">0%</span>
2. 使用 XMLHttpRequest 监听上传进度
关键点:必须在调用 xhr.open() 之后、xhr.send() 之前绑定 xhr.upload.onprogress;且后端需支持 CORS(若跨域)并正确响应(如返回 200):
示例代码:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
const fileInput = document.getElementById('fileInput');const uploadBtn = document.getElementById('uploadBtn');
const progressBar = document.getElementById('progressBar');
const progressText = document.getElementById('progressText');
uploadBtn.addEventListener('click', () => {
if (!fileInput.files.length) return;
const file = fileInput.files[0];
const xhr = new XMLHttpRequest();
// 监听上传进度
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
progressBar.value = percent;
progressText.textContent = Math.round(percent) + '%';
}
};
// 上传完成
xhr.onload = () => {
if (xhr.status === 200) {
alert('上传成功');
} else {
alert('上传失败:' + xhr.statusText);
}
};
// 开始上传
xhr.open('POST', '/upload'); // 替换为你的后端接口
const formData = new FormData();
formData.append('file', file);
xhr.send(formData);
});
3. 注意事项与常见问题处理
-
必须设置
enctype="multipart/form-data"? 不需要 ——FormData自动处理,但表单提交时才需设该属性;JS 用xhr.send(formData)时无需手动设置。 -
为什么 onprogress 不触发? 常见原因:后端未正确响应(如返回 500)、未开启 CORS(
Access-Control-Allow-Origin等头缺失)、或上传的是空文件(e.total === 0)。 -
移动端兼容性:iOS Safari 从 iOS 11.3+、Android Chrome 50+ 均支持
upload.onprogress,基本无须降级。 -
多个文件上传:可遍历
files数组,逐个上传,或合并为一个FormData并添加多个append('file', file, filename),后端需对应接收多文件。
4. 进阶:显示剩余时间或上传速度(可选)
可在 onprogress 中记录时间戳和已上传字节数,计算瞬时速率:
let lastLoaded = 0;
xhr.upload.onprogress = (e) => {
if (!startTime) startTime = Date.now();
if (e.lengthComputable) {
const now = Date.now();
const elapsed = (now - startTime) / 1000; // 秒
const speed = (e.loaded - lastLoaded) / (now - startTime) * 1000; // 字节/秒
lastLoaded = e.loaded;
// 可更新 UI 显示 "速度:xx KB/s,预计剩余 xx 秒"
}
};

















