前端JavaScript获取文件的真实格式

背景:

最近处理(vue2+js)上传文件,后端识别文件中的敏感词的需求,发现如果用户篡改文件后缀,比如把txt文件改为doc,则后端识别不出文件中的敏感词。

原因分析:

前端vue项目+element ui中,el-upload组件中一般是在before-upload钩子函数中控制上传的文件类型,一般通过截取fileName后缀来判断文件类型,针对于篡改后的文件,识别不出源文件类型。

方案思路:

采用读取文件的十六进制文件头来判断文件的真正类型

开发步骤:

1.定义枚举,建立常见的文件类型与文件头魔数对应关系

const FILE_MAGIC_NUM = new Map([
['doc',[0xD0,0xCF,0x11,0xE0]]
])

2.读取文件的二进制流,用二进制视图定型数组的Uint8Array获取文件的魔数,判断该文件魔数是否符合文件的魔数

const checkRealFileType = (file) => {
    const jpegHeader = [0xff, 0xd8, 0xff];// jpeg类型的魔数
    const reader = new FileReader();
    reader.onload = () => {
      // 读取文件二进制流
      const arrayBuffer = reader.result;
      // 用二进制视图定型数组的Uint8Array获取文件的魔数
      const uint8Array = new Uint8Array(arrayBuffer);
      const magicNum = uint8Array.slice(0, jpegHeader.length);
      // 判断该文件魔数是否符合jpeg的魔数
      const isJpeg = jpegHeader.every((header, index) => {
        return header === uint8Array[index];
      });

      console.log('源文件', file);
      console.log('jpeg的魔数', jpegHeader);
      console.log('文件流中的魔数', { magicNum });
      console.log('文件真实类型是否为jpeg', isJpeg);
    };
    reader.readAsArrayBuffer(file);
  };

3.在el-upload上传组件before-upload钩子函数中,引用该方法,但因为异步问题,达不到预期效果,所以封装了一个 readBuffer 函数,用于读取文件中指定范围的二进制数据。

function readBuffer(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      resolve(reader.result);
    };
    reader.onerror = reject;
    reader.readAsArrayBuffer(file);
  });
}

方案参考链接:

JS如何判断文件的真实类型 - 掘金 (juejin.cn)

JavaScript 如何检测文件的类型? - 掘金 (juejin.cn)

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值