加multiple属性仅支持多选,还需正确读取FileList、逐个append文件、处理兼容性及前后端校验。常见错误是取files[0]、误用value、未转真数组、FormData传参不当、忽略iOS Safari限制等。

加 multiple 属性就能批量选择,但只加这个远远不够——用户能多选,不代表你代码能正确读取、上传或校验。
为什么加了 multiple 还是只能拿到一个文件
常见错误是 JS 里硬编码取 input.files[0],而忽略了 input.files 是一个类数组的 FileList 对象,不是普通数组。它只读,不能直接用 map 或 forEach。
- 必须先转成真数组:
Array.from(input.files)或[...input.files] - 检查数量要用
input.files.length,而不是input.value(后者只返回伪造路径,且永远只反映第一个文件) - 遍历时别漏掉大文件或重复文件:同一文件被多次选择时,
FileList在部分浏览器中会去重,但行为不一致,不能依赖
移动端和旧版 Safari 的兼容性坑
iOS Safari 在 16.4 版本前基本不支持 multiple,点开仍是单选;Android 主流浏览器支持良好,但部分国产 WebView 可能阉割该能力。
- 检测是否生效:监听
change事件后打印input.files.length,若始终为 1,大概率是环境限制 - 降级方案不是“禁用”,而是提示用户“请使用 Chrome 或更新系统”,并保留单文件上传逻辑
- 不要用
capture属性(如capture="user"),它会强制调起摄像头/麦克风,同时禁用multiple
FormData.append 怎么传多个文件才不丢
后端收不到全部文件?90% 卡在 FormData.append() 写法上。不能把整个 FileList 一次性 append,必须逐个处理。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
formData.append('files', file)—— 第二个参数必须是File实例,不是file.name或字符串 - 字段名统一用复数(如
'files'),后端才能按数组解析;PHP 看$_FILES['files']['name']数组,Express + multer 要配upload.array('files') - 如果服务端要求带索引(如
files[0]),就用formData.append(`files[${i}]`, file),但需前后端协议对齐
真正麻烦的从来不是“怎么选”,而是“选完之后怎么不崩”:前端截断数量、过滤重复、校验大小、显示进度,后端二次验证、防内存溢出、处理文件名安全——这些环节漏掉任意一环,上线后都会变成半夜告警。



















