<p>应使用 file.size / (1024 * 1024) 转 MB,四舍五入保留一位小数,避免用 1000 换算或未判空取 size;小于 1MB 时降级显示 KB。</p>

直接用 file.size 除以 1024 * 1024 就行,但要注意四舍五入和单位精度
浏览器里拿到的 file.size 单位永远是字节(bytes),想转 MB 就是纯数学换算:除以 1024 * 1024。别用 1000 * 1000,那不是二进制单位,服务端校验或后端日志对不上。
常见错误现象:
- 写成
size / 1000 / 1000→ 显示值偏大,比如 1048576 字节(1 MiB)会显示成 "1.048576 MB" 而非 "1.0 MB" - 不做
toFixed(1)或类似处理 → 页面显示一长串小数,如 "2.3456789012345677 MB" - 没判断
file是否存在就取.size→ 控制台报Cannot read property 'size' of undefined
实操建议:
- 用
Math.round(size / (1024 * 1024) * 10) / 10得到保留一位小数的 MB 值(比toFixed更稳妥,避免字符串转换) - 如果文件小于 1MB,可降级显示 KB:
size - 别在 HTML 模板里硬写计算逻辑,比如
<p>{{ file.size / 1024 / 1024 }}</p>—— 原生 HTML 不解析表达式,只会原样输出
用 Intl.NumberFormat 格式化更可靠,但得注意 Safari 13+ 才支持
如果你需要本地化(比如德语显示 "2,3 MB" 而非 "2.3 MB")、自动千分位、或统一控制小数位数,Intl.NumberFormat 是比手写 toFixed 更健壮的选择。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 创建一次 formatter 复用:
const mbFormatter = new Intl.NumberFormat('zh-CN', { maximumFractionDigits: 1, notation: 'standard' }); - 调用时先换算:
mbFormatter.format(size / (1024 * 1024)) + ' MB' - 旧版 Safari(notation 选项,若需兼容,降级用
Math.round(...)分支 - 别传负数或
NaN给format(),否则返回空字符串;加一层isFinite()判断更安全
input[type="file"] 的 change 事件里必须检查 files[0] 才能读 size
用户点“取消”或没选任何文件时,event.target.files 是空的 FileList,直接访问 [0].size 会报错。
实操建议:
- 务必先判空:
if (!event.target.files.length) return;或const file = event.target.files[0]; if (!file) return; - 不要只依赖
files.length === 0,有些浏览器(尤其移动端)可能返回files.length === 1但file是 null,所以要双重检查file?.size - 如果用了
multiple属性,别默认只取[0],要遍历files并分别处理每个file.size
上传前校验大小,别只靠显示——防止用户绕过 UI 直接发超限请求
把字节转 MB 只是为了显示友好,但真正拦住超限文件得靠 JS 校验 + 后端兜底。光显示 "5.2 MB" 不代表它能成功上传。
实操建议:
- 设定明确阈值(如 5 * 1024 * 1024),在
change回调里立刻比对:if (file.size > MAX_SIZE) { alert('文件不能超过 5 MB'); input.value = ''; return; } - 清空
input.value是关键,否则用户再次点击选择框时,浏览器可能缓存上次文件,不触发change事件 - 别信
accept属性能限制大小——它只管 MIME 类型,对 size 完全无效 - 前端校验只是体验优化,后端必须重新检查
Content-Length或实际接收字节数,否则恶意用户改 JS 就能绕过
文件大小格式化本身很简单,难的是边界情况:空文件、超大文件(>2GB 时 size 在某些旧 Android 浏览器里可能不准)、用户反复快速切换文件导致事件竞争、以及把“显示逻辑”和“校验逻辑”混在一起造成漏判。真正上线前,至少在 Chrome、Safari(iOS 16+)、Edge 最新版上用真实文件测一遍 size 读取是否稳定。



















