Vue.js中如何校验上传文件真实格式(防扩展名篡改)
在Vue.js中校验文件真实格式的高效方案
要解决用户篡改扩展名绕过校验的问题,核心是校验文件的Magic Number(文件头二进制标识)——这是文件真实格式的唯一标识,和扩展名无关。下面是一套轻量、低侵入的Vue实现方案:
1. 定义文件类型与Magic Number的映射
先整理常见文件的Magic Number(可根据需求扩展):
const FILE_MAGIC_MAP = { png: [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A], jpeg: [0xFF, 0xD8, 0xFF], pdf: [0x25, 0x50, 0x44, 0x46] // 对应字符 "%PDF" };
2. 实现文件真实类型校验函数
在Vue组件中封装异步校验方法,仅读取文件前几个字节(无需加载整个文件,性能拉满):
async validateRealFileType(file, expectedType) { const targetMagic = FILE_MAGIC_MAP[expectedType.toLowerCase()]; if (!targetMagic) return false; return new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => { const fileHeader = new Uint8Array(e.target.result); // 逐字节对比Magic Number const isMatch = targetMagic.every((byte, idx) => fileHeader[idx] === byte); resolve(isMatch); }; // 仅读取文件头部的指定字节数 reader.readAsArrayBuffer(file.slice(0, targetMagic.length)); }); }
3. 在上传流程中集成校验
在文件选择的change事件中调用校验,替换原有扩展名校验逻辑:
<template> <input type="file" @change="handleFileSelect" accept=".png,.jpeg,.pdf" /> </template> <script> export default { methods: { async handleFileSelect(e) { const file = e.target.files[0]; if (!file) return; // 提取用户提供的扩展名(仅做辅助,核心看真实格式) const fileExt = file.name.split('.').pop().toLowerCase(); // 校验真实格式 const isValid = await this.validateRealFileType(file, fileExt); if (!isValid) { alert(`检测到文件真实格式与扩展名不符,请上传正确格式的文件!`); e.target.value = ''; // 清空文件选择 return; } // 校验通过,执行后续上传逻辑 // this.uploadToServer(file); }, async validateRealFileType(file, expectedType) { const FILE_MAGIC_MAP = { png: [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A], jpeg: [0xFF, 0xD8, 0xFF], pdf: [0x25, 0x50, 0x44, 0x46] }; const targetMagic = FILE_MAGIC_MAP[expectedType.toLowerCase()]; if (!targetMagic) return false; return new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => { const fileHeader = new Uint8Array(e.target.result); const isMatch = targetMagic.every((byte, idx) => fileHeader[idx] === byte); resolve(isMatch); }; reader.readAsArrayBuffer(file.slice(0, targetMagic.length)); }); } } }; </script>
关键注意事项
- 前端校验仅做拦截,后端必须二次校验:前端逻辑可被篡改,后端要复用同样的Magic Number校验逻辑,保证数据安全。
- 扩展性强:如需支持更多文件类型,只需在
FILE_MAGIC_MAP中添加对应Magic Number即可。 - 性能优异:仅读取文件头部几个字节,大文件也不会有加载延迟。
内容的提问来源于stack exchange,提问作者test user
相关产品推荐
相关产品推荐

