前端无法100%确认逻辑损坏,但可通过三步轻量验证快速筛出明显异常:1.读取文件头(magic number)校验格式合法性;2.检查文件大小是否为0或低于业务阈值;3.对图片类文件创建Blob URL并用Image加载测试解码能力;所有检查均基于浏览器原生API,仅作前端快速排除,不可替代服务端校验。

前端无法 100% 确认文件是否“逻辑损坏”(比如视频能打开但关键帧丢失),但可以通过几个低成本、高价值的检查,在上传前快速筛出明显异常的文件。核心思路是:不依赖后端,用浏览器原生 API 做轻量验证。
读取文件头(magic number)校验格式合法性
大多数文件类型在开头固定字节有唯一标识(如 PNG 是 89 50 4E 47,PDF 是 25 50 44 46)。如果用户改了扩展名但内容不是对应格式,或传输截断,这里会立刻暴露。
- 只读前 4 字节就够覆盖绝大多数常见格式(图片、PDF、ZIP、Office 文档等)
- 不能只靠
file.type—— 这个值由浏览器根据扩展名或 MIME 推测,完全可伪造 - 注意:
FileReader.readAsArrayBuffer()是异步的,需配合Promise封装
async function validateFileHeader(file, expectedBytes) {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onload = () => {
const buf = new Uint8Array(reader.result);
const matches = expectedBytes.every((b, i) => buf[i] === b);
resolve(matches);
};
reader.onerror = reject;
reader.readAsArrayBuffer(file.slice(0, expectedBytes.length));
});
}
// 使用示例:检查是否为 PNG
validateFileHeader(file, [0x89, 0x50, 0x4E, 0x47]).then(isValid => {
if (!isValid) console.warn("文件头不匹配,可能不是合法 PNG");
});
检查文件大小是否为 0 或异常小
文件大小为 0 字节,基本等于没传成功;而某些场景下(如网络中断、表单提交过早),文件可能只有几百字节,远低于合理下限(例如一个 JPEG 不可能只有 1KB)。
-
file.size === 0是最廉价、最确定的损坏信号 - 对特定类型可设阈值:PDF ≥ 1KB,MP4 ≥ 100KB,Excel ≥ 5KB —— 阈值要结合业务实际调整
- 不要仅对比“预期大小”,因为用户上传的原始文件尺寸本就不可控
尝试解析为 Blob URL 并触发简单加载(仅图像)
对图片类文件,可以进一步试探性加载——不是为了显示,而是看浏览器能否解码。这能发现“头信息正确但内部数据错乱”的情况(如部分 JPEG 校验失败)。
立即学习“前端免费学习笔记(深入)”;
- 创建
URL.createObjectURL(file)后,用Image对象加载,监听onload和onerror - 必须调用
URL.revokeObjectURL()清理,否则内存泄漏 - 仅适用于
image/*类型;其他类型(如 PDF、视频)无通用轻量加载方式
function testImageIntegrity(file) {
return new Promise((resolve) => {
if (!file.type.startsWith('image/')) {
resolve(true); // 跳过非图片
return;
}
const url = URL.createObjectURL(file);
const img = new Image();
img.onload = () => { URL.revokeObjectURL(url); resolve(true); };
img.onerror = () => { URL.revokeObjectURL(url); resolve(false); };
img.src = url;
});
}
为什么不能只信 file.name 或 file.type
这两个字段都来自用户操作系统或浏览器推测,完全不受控:
-
file.name可以是任意字符串,哪怕传的是二进制乱码,也能叫report.pdf -
file.type在 Chrome/Firefox 中常为空,或根据扩展名瞎猜(如把.txt改成.jpg,type 就变成image/jpeg) - 真正可靠的数据只有
file.size和文件内容本身(通过FileReader读取)
最容易被忽略的是:这些检查全在上传前做,但它们只是“快速排除明显坏文件”,不是替代后端校验。真正的完整性(比如哈希比对、流式解码验证)必须由服务端完成——前端永远可绕过。



















