必须加 multiple 属性且仅对 type="file" 有效,正确写法是<input type="file" name="files[]" multiple>;表单需设 enctype="multipart/form-data";JS 应遍历 input.files 而非 value;FormData 需多次 append 同名 key;iOS Safari 16.4 前存在兼容问题。

必须加 multiple 属性,且只对 type="file" 有效
不加 multiple,浏览器原生就禁止多选——JS 无法绕过这个限制。它不是可选项,是开关。
✅ 正确写法:<input type="file" name="files[]" multiple>
❌ 常见错误:<input multiple>(缺 type)、<input type="text" multiple>(类型不对)、<input type="file" multiple="false">(布尔属性不接受值,写了反而被当成 true)
name 用 files[] 是为了兼容 PHP 等后端自动解析为数组;Node.js 的 multer 也认 upload.array('files'),比纯 files 更稳妥。
enctype="multipart/form-data" 缺一不可
表单没设这个属性,文件数据根本不会发出去——连 Network 面板都看不到文件字段。
必须同时满足:
- <form method="POST" enctype="multipart/form-data">
- <input type="file" multiple>
- 用户实际选了多个文件
漏掉任意一个,都会表现为“只能传一个”或“后端收不到文件”。调试时先看 Request Payload 里有没有多个 files 条目,而不是直接怀疑 JS 逻辑。
立即学习“前端免费学习笔记(深入)”;
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
JavaScript 读取时别碰 value,要遍历 files
input.value 只返回第一个文件的伪造路径(如 C:\fakepath\photo.jpg),对多文件毫无意义。
真正承载所有文件的是 input.files,它是一个只读的 FileList 对象:
- 检查数量:input.files.length —— 为 0 时别直接取 files[0]
- 转成真数组处理:Array.from(input.files),之后才能用 forEach、map 等
- 每个 file 是 File 实例,有 name、size、type、lastModified,可用于校验
- 别 JSON.stringify(input.files) —— 结果是空对象,因为 FileList 不可序列化
FormData 中必须用相同 key 多次 append()
后端只收到一个文件?大概率卡在这步。
❌ 错误写法:formData.append('files', file) 循环多次 → 多数后端(Express 默认、PHP)会覆盖,只剩最后一个
✅ 正确写法:
对每个文件都调一次 formData.append('files', file),key 名完全一致
后端需启用「同名多值」解析:
- Express + multer:用 upload.array('files'),不是 upload.single()
- PHP:遍历 $_FILES['files']['name'] 数组,逐个取 $_FILES['files']['tmp_name'][$i]
别手动设置 Content-Type 请求头——浏览器会自动设为 multipart/form-data 并生成正确 boundary。
iOS Safari 在 16.4 之前会静默忽略 multiple,input.files.length 始终为 1,且无任何提示。检测方式:navigator.userAgent.includes('iPhone') && /OS [1-9]\d?_[0-3]/.test(navigator.userAgent)。这不是前端能修复的问题,只能提示用户换浏览器或升级系统。


















