multiple属性仅对input[type="file"]有效,可实现真多文件选择;size属性对其无效,仅适用于text等输入类型,控制文件输入框大小须用CSS。

multiple 属性只对 input[type="file"] 有效,加了它才能真选多个文件;size 属性在 input 上根本不起作用——别被名字误导,它只存在于 <select></select> 和某些老式表单控件里,对文件输入框完全无效。
为什么 size 对 input[type="file"] 没用
HTML 规范里,size 是为 <select multiple></select> 或单行文本输入(如 type="text")设计的显示宽度控制属性。但 input[type="file"] 的 UI 完全由浏览器渲染,不响应 size、width 或内联样式(除非用 CSS 覆盖伪元素)。你写 <input type="file" size="10">,浏览器会忽略它,连 warning 都不抛。
想控制文件输入框视觉大小?只能靠 CSS:width、padding、font-size 等生效,但注意:不同浏览器对 ::file-selector-button 和 ::file-selector-field 的支持程度不一,iOS Safari 尤其保守。
multiple 正确启用多文件选择的硬性条件
必须同时满足以下四点,用户才能真正一次选多个文件:
立即学习“前端免费学习笔记(深入)”;
-
type必须是"file"——type="email"加multiple只是放宽校验,不提供多选 UI -
multiple是布尔属性,写成multiple或multiple=""都行,但multiple="false"反而会被当成true - 不能同时设置
capture属性 —— 否则 iOS 和部分 Android 会强制切到单文件拍摄/录音模式,禁用多选 - 用户操作要符合系统习惯:Windows/Linux 按住
Ctrl点击,macOS 按住Cmd,或直接框选/拖入多个文件
读取和上传多个文件时最常踩的坑
input.value 永远只返回第一个文件名(且是伪造路径),绝不能用来判断选了多少个文件;真正可用的是 input.files,但它是个类数组的 FileList,不是 Array。
- 遍历必须用
for (const file of input.files)或Array.from(input.files).forEach(...)—— 直接调.map()会报错 - 上传时要用
FormData.append('files', file)循环调用,不能append('files', input.files)—— 后者在 Chrome 和 Firefox 行为不一致,且后端收不到数组 - iOS Safari 在 16.4 之前基本不支持多选,Android 厂商定制系统(如华为 EMUI、小米 MIUI)也可能阉割该功能,降级方案得提前准备:比如允许重复单选 + 合并
FileList - 用户拖入重复文件时,
FileList里会出现两份同名项,前端需按file.name + file.size + file.lastModified组合去重
accept 和 multiple 的配合效果很有限
accept 只影响文件选择弹窗里的过滤项,不能阻止用户绕过界面粘贴或拖入非法类型文件。比如设了 accept="image/*",用户仍可拖进一个 .exe 文件,input.files 里照样出现,file.type 可能为空或错误。
真正可靠的校验必须放在上传前:
- 前端检查
file.type和file.name后缀,但仅作提示 —— 用户可轻易伪造 - 服务端必须做 MIME 类型检测、文件头校验、大小限制(如 PHP 的
upload_max_filesize、Nginx 的client_max_body_size) - 别依赖
multiple控制并发或上传粒度 —— 它只管选择,不管传输;传 100 个大文件容易触发内存溢出或超时,得自己分批或流式处理
最易被忽略的一点:即使写了 multiple,也得检查 input.files.length 是否大于 0 再执行后续逻辑 —— 用户可能点了取消,或者浏览器兼容性导致实际没选中任何文件。



















