multiple属性无法限制文件数量,须用javascript干预:监听change事件,用array.from(files).slice(0,5)截取前n个存入自定义数组;防重复用name-size-lastmodified组合标识;提交前校验selectedfiles长度,服务端必须二次校验。

multiple 属性本身不提供数量限制能力,必须靠 JavaScript 主动干预 —— 否则用户一次选 100 个文件,前端就传 100 个,后端才报错,带宽和体验都白耗。
监听 change 事件并截断 files 列表
用户点击选择后,input[type="file"].files 是只读的 FileList,不能直接删元素。常见错误是试图 files.pop() 或 files.splice(),这会报错。
- 正确做法:用
Array.from(files).slice(0, 5)提取前 N 个,再存入你自己的数组(如selectedFiles = []) - 别直接赋值回
input.files—— 它不可写,强行操作无效 - 若想“清空重选”,可设
input.value = '',但注意这会丢失已选文件,适合纯单次限制场景 - 移动端(尤其微信内置浏览器)可能触发多次
change,建议加防抖或标记处理状态
去重判断避免重复计入总数
用户反复打开文件选择框,很容易再次选中同一个文件(比如两次都点中 report.pdf),仅靠 file.name 判断不准 —— 文件名相同但内容不同,或内容相同但名字被改过。
- 推荐组合标识:
${file.name}-${file.size}-${file.lastModified} - 用
Set存这些字符串,每次新增前先检查是否已存在 - 注意:
file.lastModified在部分旧 Android 浏览器中可能为0,可降级为只比name + size - 不建议用
URL.createObjectURL(file)做哈希 —— 开销大、内存泄漏风险高
提交前用 FormData 再校验一次
前端限制只是体验层,JS 可被禁用或绕过。如果上传逻辑支持直接调用 fetch 或 XMLHttpRequest,攻击者能跳过 UI 直接塞 50 个文件进 FormData。
- 构造
FormData时,显式遍历你维护的selectedFiles数组,而不是读input.files - 在
fetch发起前加一句if (selectedFiles.length > 5) throw new Error('超出上传上限') - 服务端仍需做相同校验 —— 这不是可选步骤,是必须项
- 别在
submit事件里只检查input.files.length,它可能已被用户手动修改或伪造
真正容易被忽略的点是:限制逻辑和 UI 更新必须同步。比如用户删掉一个文件,但你没及时更新计数器或禁用上传按钮,就可能让总数临时超限;更隐蔽的是,File 对象长期驻留在内存里(尤其在 React/Vue 组件中作为 state),大文件多几个就会卡顿 —— 上传成功后记得设 file = null 或从数组中 splice 掉引用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











