multiple属性仅对type="file"有效,可触发系统多选对话框;若失效,常见原因包括form未设enctype="multipart/form-data"、后端误用单文件接收、name属性未正确命名、手动覆盖Content-Type,以及混淆input.files与value。

multiple 属性只对 type="file" 有效
它不是通用多选开关,加在 select 或其他表单控件上完全没用。只有 才能触发系统级多选对话框——按住 Ctrl/Cmd 点选、框选、拖拽多个文件都靠它。漏掉这个属性,哪怕 JS 写得再复杂,用户点一次也只会弹出单文件选择器。
为什么加了 multiple 还是只传了一个文件
常见原因不是前端没选对,而是后端或表单配置断链了:
-
form没设enctype="multipart/form-data":文件数据压根不会进请求体,input.files再多也没用 - 后端用
req.file(Express multer 单文件中间件)接收,而不是req.files或upload.array('files') -
name属性写成name="file"而非name="files[]"或name="files",导致 PHP/Node.js 解析时覆盖而非追加 - 手动设置了
Content-Type请求头:浏览器自动加的multipart/form-data; boundary=...被覆盖,后端解析器直接丢弃整个 body
input.files 和 value 完全不是一回事
value 是个伪造路径字符串(如 C:\fakepath\photo.jpg),且永远只显示第一个文件;真正要操作的是 input.files,它是个只读的 FileList 对象:
- 不能
JSON.stringify(input.files)——结果是{},因为FileList不可序列化 - 遍历时必须用
for (let i = 0; i 或转数组:Array.from(input.files) - 每个
file是File实例,有name、size、type、lastModified,可用于实时校验(比如限制总大小或单个超 100MB 就报错)
用 FormData.append() 传多个文件的关键细节
后端能否收到全部文件,取决于你 append 的方式和后端是否启用同名多值解析:
- ✅ 正确:
formData.append('files', file1); formData.append('files', file2);—— 同名 key 多次调用,后端需按数组处理 - ❌ 错误:
formData.append('files', [file1, file2]);—— 把数组当一个 blob 传,后端收不到独立文件 - 调试必看 Network 面板的 Request Payload:每个文件应作为独立条目出现,而不是合并成一个 blob
- iOS 16.4 以下版本不支持
multiple,需降级为单次多选 + 手动累加,或提示用户升级
实际上传逻辑里最容易被跳过的,是「选完立刻校验并反馈」——别等用户点了提交才告诉ta“你选了52个文件,服务器扛不住”,而应在 change 回调里就显示数量、总大小、类型分布,并拦截明显异常的组合(比如 1 个 500MB 视频 + 49 个 PDF)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











