accept 属性仅过滤文件类型,无法限制文件大小;真正控制大小需在 javascript 的 change 事件中遍历 input.files 校验 file.size,并注意移动端兼容性、name 写法、formdata 正确添加及服务端多文件解析配置。

accept 属性只能过滤文件类型,不能限制大小
很多人误以为 accept 能拦住超大文件,其实它只影响系统文件选择器的界面过滤——比如设成 accept="image/*",Windows/macOS 会默认只显示图片,但用户仍可手动切换到“所有文件”,然后选一个 5GB 的视频。浏览器不会因此报错或拦截,input.files 里照样拿到那个大文件对象。
真正能做大小控制的是 JavaScript:必须在 change 事件里读 file.size(单位字节),并主动校验。常见错误是只校验第一个文件:input.files[0].size,而忽略了 multiple 下可能有几十个文件。
- 单文件限制示例:
if (file.size > 10 * 1024 * 1024) { alert("单个文件不能超过10MB"); return; } - 多文件需遍历:
Array.from(input.files).every(file => file.size - 注意:部分浏览器(如 Chrome)对 >2GB 的文件可能返回
size: 0或抛SecurityError,建议加try/catch
multiple + accept 组合使用时的典型陷阱
multiple 和 accept 可以共存,但它们职责完全不同:multiple 控制能否多选,accept 仅提供 UI 层提示。两者叠加并不自动增强安全性,反而容易让人放松警惕。
- 移动端兼容性差:iOS Safari 在 16.4 之前完全忽略
multiple,点选后只弹单文件选择器;即使写了accept="image/*,.pdf",旧版 Android 浏览器也可能无视 -
accept值写法要严谨:用逗号分隔多个 MIME 类型时,空格会导致失效,比如accept="image/png, image/jpeg"中的空格会让第二个类型被忽略 - 不要依赖
file.type判断真实类型:它由浏览器根据扩展名或魔数推测,可被轻易伪造;后端必须重新校验文件头或内容
表单提交时 name 属性怎么写才支持多文件后端接收
前端 multiple 选中的文件,最终能不能被后端当数组接收,关键不在 HTML,而在 name 的写法和后端框架解析逻辑。
- 推荐写法:
<input type="file" name="files[]" multiple>—— 方括号是 PHP/ThinkPHP/Laravel 等主流框架识别数组的惯例,但不是 HTML 标准 - 更通用写法:
name="files"+ 后端按同名字段聚合(如 Node.js 的multer默认把同名多文件转为数组) - 绝对避免:
name="file"单数形式且无方括号,某些老框架(如早期 Java Servlet)可能只取第一个文件 - form 必须带
enctype="multipart/form-data",否则文件根本不会发出去
JavaScript 上传多个文件时 FormData.append 的正确姿势
别直接把 input.files 整个塞进 FormData.append()。虽然 formData.append('files', input.files) 在 Chrome 里看似能传多个,但在 Firefox 或 Safari 中大概率只传第一个,行为不一致。
- 正确做法是循环调用:
Array.from(input.files).forEach((file, i) => formData.append('files', file)) - 如果需要保留原始顺序或标记索引,可用
formData.append('files[' + i + ']', file) - 并发上传别硬开 20 个
fetch:浏览器对同一域名并发请求数有限制(通常 6–10),推荐用Promise.allSettled()控制并发数(例如每次最多 4 个) - 大文件上传前务必检查
file.size,否则用户点完“上传”后卡死在 JS 里,连错误都来不及提示
实际开发中,最易被跳过的环节是服务端对 multipart/form-data 中重复字段的解析配置——哪怕前端 name 写对了、JS 也 append 对了,Nginx 或后端框架若没开启多值支持,照样只收第一个文件。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











