用 array.from(input.files).reduce((sum, file) => sum + file.size, 0) 累加所有文件 size;需转为真数组才能遍历,单看 files[0]?.size 会漏检多文件总和超限;单位换算应基于1024并保留1位小数。

怎么用 FileList 累加所有文件的 size
多文件上传时,input[type="file"].files 返回的是只读的 FileList 对象,不能直接用数组方法。必须转成数组才能遍历求和。
- 用
Array.from(input.files)或[...input.files]转为真数组 - 每个
File对象都有size属性(单位字节),直接累加即可 - 注意:如果用户取消再重选,
files会全新替换,不是增量更新
const input = document.getElementById('fileInput');
input.addEventListener('change', () => {
const totalSize = Array.from(input.files).reduce((sum, file) => sum + file.size, 0);
console.log('总大小:', totalSize, '字节');
});
为什么不能只看第一个文件的 size 就判断超限
常见错误是只检查 input.files[0]?.size,这在 multiple 场景下完全失效——它只反映首个文件大小,漏掉其余所有文件。
- 比如用户选了 10 个 800KB 的文件,单个不超限,但总和已超 8MB
- 服务端校验也得按总和来,否则可能被绕过(如分多次提交)
- 前端提示应明确写“已选 5 个文件,总计 7.2 MB”,而不是“最大单文件 5MB”
如何把字节数转成易读格式(KB/MB/GB)
直接显示字节对用户不友好,需要做单位换算。注意别用 Math.round 粗暴取整,小文件容易显示为 0 KB。
- 推荐除以 1024 并保留 1 位小数:
(bytes / 1024).toFixed(1) + ' KB' - 超过 1024 KB 再升一级:
(bytes / (1024 * 1024)).toFixed(1) + ' MB' - 避免用 1000 做除数(那是十进制,文件系统是二进制)
总大小校验要和服务端逻辑严格对齐
前端统计只是提示和拦截,真正生效的限制在后端。但前后端计算方式不一致会导致体验断裂。
- 比如前端按
files[i].size求和,后端却按接收到的 multipart body 总长度判断——两者可能差几百字节(边界符、字段名开销) - 更稳妥的做法:前端预留 1–2% 余量(如限制 100MB,则前端报 98MB 就警告)
- 若服务端做了分块上传(如每块 2MB),总大小校验必须在所有块合并后执行,不能只看单块
最易被忽略的一点:拖拽上传场景下,event.dataTransfer.files 和 input.files 是两套对象,统计逻辑要复用同一套函数,别写两遍。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











