multiple属性必须添加,否则浏览器原生仅允许单文件选择;常见失效原因包括缺少enctype="multipart/form-data"、name未用数组格式(如files[])、method非post,以及ios safari 16.4以下版本静默忽略该属性。

multiple 属性必须加,否则浏览器原生只允许选一个文件——这不是 JavaScript 能绕过的限制,是 HTML 规范级行为。
为什么加了 multiple 还是只能选一个文件
常见原因不是代码写错,而是漏掉了配套条件:
-
<input type="file">必须同时带type="file"和multiple,单独写multiple无效 - 表单
<form></form>缺少enctype="multipart/form-data":文件数据根本不会发出,Network 面板里看不到任何文件字段 - 没设
name属性,或写成name="files"(不带方括号):PHP 会覆盖同名字段,Express + multer 默认收不到数组 - iOS Safari 版本低于 16.4:该属性被静默忽略,用户点多少次都只能选一个,且无报错提示
input.files 不是数组,遍历时容易报错
input.files 是只读的 FileList,类数组但没有 .forEach()、.map() 等方法。直接调用会抛 TypeError: input.files.forEach is not a function。
- 安全转数组:用
Array.from(input.files)或[...input.files] - 别对
input.files做JSON.stringify():结果是空对象{},因为FileList不可序列化 - 每个
file是File实例,有name、size、type、lastModified,可用于前端校验 - 不要等用户选完 50 个文件再显示数量,应在
change后立刻更新 UI,避免误判“卡死”
FormData 上传多个文件时 key 名怎么写
后端能否收到全部文件,取决于你往 FormData 里怎么 append:
- ❌ 错误写法:
formData.append('files', file1); formData.append('files', file2)—— 多数后端默认当单值处理,只保留最后一次 - ✅ 正确写法:用相同 key 名多次
append,如formData.append('files', file1); formData.append('files', file2),但后端必须启用「同名多值」解析(如 Express 的upload.array('files')) - 别手动设置
Content-Type请求头:让浏览器自动设为multipart/form-data并生成合法boundary - 调试必看 Network → Payload:确认每个文件是否作为独立条目出现,而不是合并成一个 blob
iOS 16.4 以下版本无法支持多选,没有降级方案
这是系统级限制,不是 bug,也无法用 JavaScript 模拟多次点击来绕过。检测到低版本 iOS Safari 时,唯一可行做法是:
- 用
navigator.userAgent+parseFloat(navigator.appVersion.match(/OS (\d+)_/)?.[1])判断 iOS 版本 - 若
- 不要尝试用
DataTransfer构造多文件列表:兼容性差,Chrome/Firefox 不支持写入input.files -
accept和multiple可共存,但它只过滤弹窗类型,不影响多选能力,也拦不住用户手动拖入不匹配类型的文件
最易被忽略的是:iOS 旧版 Safari 的失效是静默的,连控制台都不报错;而 FormData 中同名 key 的 append 行为,和后端解析逻辑必须严格配对,差一个字符(比如 'file' vs 'files')就会丢数据。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











