必须显式添加multiple属性,否则浏览器仅允许单选;event.target.files是只读FileList,需转数组处理;上传时应循环formData.append('files', file),并注意iOS Safari 16.4+才稳定支持。

HTML <input type="file"> 多文件上传怎么启用
默认情况下,<input type="file"> 只允许选中单个文件。要支持多文件,必须显式添加 multiple 属性,否则浏览器会忽略后续选择的文件。
常见错误是只写了 <input type="file"> 就以为能多选,结果调试半天发现 event.target.files 始终只有 1 个。
-
<input type="file" multiple>—— 必须加,无例外 - 可配合
accept限制类型,例如accept="image/*,.pdf" - 不支持设置默认值(
value属性会被浏览器忽略) - 移动端 Safari 对
multiple支持较晚(iOS 16.4+ 才稳定支持多图上传)
JavaScript 如何读取并渲染上传文件列表
用户选择后,event.target.files 是一个 FileList 对象(类数组,只读),不能用 .map() 直接调用,需先转为数组。
渲染列表时建议用 File.name、File.size 和 File.type,避免直接读取内容(除非真要预览)。
立即学习“前端免费学习笔记(深入)”;
- 转数组:
[...event.target.files]或Array.from(event.target.files) -
File.size单位是字节,建议格式化为 KB/MB(如Math.round(f.size / 1024)) - 注意:
FileList不响应式,DOM 更新需手动触发(比如清空再重写innerHTML或用append()) - 不要在循环里反复调用
URL.createObjectURL(file)后不释放——内存泄漏高发区
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
const files = [...e.target.files];
const listEl = document.getElementById('file-list');
listEl.innerHTML = '';
files.forEach(f => {
const li = document.createElement('li');
li.textContent = `${f.name} (${(f.size / 1024).toFixed(1)} KB)`;
listEl.append(li);
});
});
为什么点击“重新选择”后列表没更新?
因为 input.value 在用户选中相同文件时不会改变(哪怕清空再选),导致 change 事件不触发。这是浏览器原生行为,不是 bug。
典型场景:用户上传了 a.jpg → 点删除 → 再点 input 选 a.jpg → 列表卡住不动。
- 解决办法:每次上传操作前,手动清空
input.value = '' - 如果用了自定义触发按钮(比如隐藏原 input,用
<button>模拟),务必在点击时同步重置value - 别依赖
input的focus或click事件来判断是否重选——它们和文件变化无关 - 更健壮的做法:把文件列表状态存在 JS 变量里,UI 渲染完全由该变量驱动,而非只监听
change
服务端接收多个文件要注意什么
前端传多个文件,后端不一定自动拆成多个独立参数。具体取决于框架和请求方式。
用 FormData 提交时,所有文件都以相同字段名(如 files)追加,服务端收到的是同名多值,不是数组对象。
- 正确追加:
formData.append('files', file1); formData.append('files', file2); - 错误写法:
formData.append('files[]', file1)—— 方括号是 PHP 特有约定,标准 FormData 不识别 - Node.js Express 需用
multer的array('files');Python Flask 用request.files.getlist('files') - 若用 fetch +
Content-Type: multipart/form-data,千万别手动设 header——浏览器会自动生成 boundary,手动设会导致解析失败



















