监听change事件时需校验files总size,用array.from(files).reduce求和而非只看files[0];前端设明确阈值如50mb并清空input.value;服务端必须同步限制总上传体大小,nginx设client_max_body_size,后端按原始body长度拦截。

监听 change 事件时校验 files 总 size
用户单次通过 <input type="file" multiple> 选中多个文件,event.target.files 返回的是只读的 FileList。限制「总容量」不是看单个文件大小,而是遍历所有 file.size 求和——这是前端唯一能实时干预的时机。
常见错误是只校验第一个文件:files[0].size,结果用户选 10 个 4MB 的图片(总 40MB)却完全没拦住。
- 用
Array.from(files).reduce((sum, f) => sum + f.size, 0)算总字节数 - 建议阈值设为明确整数,比如
50 * 1024 * 1024(50MB),避免用50 * 1000 * 1000引发歧义 - 超限时清空
input.value = '',否则用户无法再次触发change(浏览器认为选择没变) - 别依赖
file.type判断是否“可信”,它可被伪造;真正要防的是体积本身
服务端必须同步限制总上传体大小
前端算出来的总 size 可被绕过:禁用 JS、手动构造 FormData、用 curl 直传。所以服务端收到请求时,必须基于整个 multipart/form-data 的原始 body 长度做拦截,而不是等解析完再判断。
典型错误是只校验每个文件的 size 字段,却忽略多个小文件累加后超出服务器承载能力。
- Nginx 层:设置
client_max_body_size 50M,否则请求根本进不到后端,直接 413 - Node.js + Express:若用
multer,limits.fieldSize控制单字段最大值,但总大小由limits.fileSize× 文件数隐含决定;更稳妥的是在中间件里读取req.headers['content-length']并拒绝超限请求 - PHP:
post_max_size必须 ≥ 你允许的总上传体积,否则即使upload_max_filesize调高也无效
避免与单文件限制逻辑混淆
HTML 的 accept 属性不参与大小控制;data-max-size 这类自定义属性只能用于单文件校验场景。一旦启用 multiple,你就得切换到「总和思维」——这和限制单个文件是两套逻辑,不能复用同一套校验函数。
容易踩的坑是把单文件限制代码直接套在 files 上,比如对每个 file 单独比对 maxSize,结果用户选 20 个 2MB 文件(总 40MB)仍能通过。
- 单独限制单文件:用
file.size - 限制总容量:用
totalSize ,且 <code>overallMax应 ≤ 服务器层配置(如 Nginx 的client_max_body_size) - 两者需同时存在:防止单个超大文件(如 2GB 视频)撑爆内存,也防多小文件凑够上限耗尽连接
大文件场景下,总容量限制会失效吗
会。当单个文件接近或超过服务端配置上限(例如 Nginx 的 client_max_body_size),浏览器可能根本无法完成上传——表现为卡住、超时、或直接返回 413。此时前端算出的「总 size」毫无意义,因为请求连第一块数据都发不出去。
真正需要关注的是:前端提示的总上限,必须 ≤ 后端和反向代理共同允许的最小值。这个最小值往往不是你写的代码,而是 nginx.conf 或 php.ini 里那个最保守的数字。
如果业务真要支持 500MB 总上传,不要只改前端和后端代码;先确认 Nginx 是否允许那么大的 client_max_body_size,再检查磁盘空间、内存缓冲区、以及上传过程中的临时文件存储路径权限——这些才是实际卡点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











