multiple属性是多文件上传的必要前提,必须添加于type="file"标签中;name建议设为files[]以便后端解析为数组;form必须设置enctype="multipart/form-data"且method为post。

multiple 属性没加,根本没法合并提交
浏览器对 input type="file" 的原生限制是硬性的:不加 multiple,用户点一次就只能选一个文件,JavaScript 无法绕过。所谓“合并一次性提交”,前提是前端能一次拿到多个文件——这一步卡住,后面全是空谈。
必须写成:<input type="file" name="files[]" multiple>。注意三点:
-
multiple是布尔属性,不能带值(multiple="false"或multiple="1"都会被当成 true) -
name="files[]"不是必须但强烈推荐:PHP 自动收为数组;Express + multer 的upload.array('files')也默认匹配这个 key - 漏掉
enctype="multipart/form-data"的<form></form>,文件数据压根不会发出去,Network 面板里看不到任何文件字段
FormData.append() 写错 key 名,后端只收到最后一个
常见错误是循环里反复用同一个 key 覆盖:formData.append('file', file) 执行 5 次,后端(如 Express 默认配置)只拿到第 5 个文件。这不是 bug,是 multipart/form-data 协议对同名字段的默认行为。
正确做法是保持 key 名一致,靠多次 append() 构建多值字段:
- ✅
formData.append('files', file)—— 每个文件都调一次,key 始终是files - 后端需启用多值解析:Express 用
upload.array('files'),不是upload.single();PHP 遍历$_FILES['files']['name']数组 - 别手动设
Content-Type请求头,让 fetch 或 XMLHttpRequest 自动处理 boundary
调试时直接看 Network → Payload,确认每个文件是否作为独立条目出现(而非合并成一个 blob)。
input.files 是 FileList,不是 Array,遍历时容易报错
input.files 是只读的类数组对象,没有 map、forEach 方法。直接写 input.files.forEach(...) 会抛 TypeError: input.files.forEach is not a function。
两种安全取法:
- 转真数组:
Array.from(input.files).forEach(file => {...}) - 传统 for 循环:
for (let i = 0; i
别碰 input.value——它只返回伪造路径(如 C:\fakepath\photo.jpg),且永远只反映第一个文件,对多文件毫无意义。
iOS 16.4 以下和大文件是隐形断点
加了 multiple 并不等于所有设备都能正常多选。iOS Safari 在 16.4 版本前基本不支持拖拽或框选,点击后仍是单文件选择框。这不是代码问题,是系统级限制,必须降级处理(例如改用多个单文件 input 或提示“请使用桌面浏览器”)。
另外,用户一次选 50 个 20MB 的文件,前端可能卡死,后端可能超时或内存溢出。真实项目中必须做两件事:
- 选完立刻校验数量与单个 size:
if (file.size > 5 * 1024 * 1024) {...} - 上传环节考虑分批或并发控制,而不是一股脑
Promise.all(uploadPromises)
最易被忽略的是 URL.createObjectURL() 后没调 URL.revokeObjectURL()——预览图多了,内存泄漏比上传失败更早让你的页面变卡。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











