最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【文件上传那些事儿】 - 02 二进制级别的格式验证

    正文概述 掘金(初心Yearth)   2021-01-15   609

    前文链接

    文件上传那些事儿】- 01 简单的拖拽上传和进度条

    V1.3:文件类型验证

    在前面的文章中,我们已经实现了一个基础的文件上传,并在此基础上做了一些简单的优化:拖拽上传和进度条,其中拖拽上传需要注意 drag 相关事件,而进度条可以使用 axios 的 onUploadProgress 来实现。

    今天我们将进一步优化这个小小的文件上传 demo,为其增加验证文件类型的功能。

    基础版:后缀

    说到验证文件类型,大家肯定都能想到,通常组件库会提供一个 beforeUpload 的方法,在这里验证文件的后缀,那我们就先用这种方式来验证一下文件类型吧。

    首先看看 file 的数据类型是怎么样的:

    【文件上传那些事儿】 - 02 二进制级别的格式验证

    可以看到,这里有一个 name 字段,我们截取最后的 .xxx 就能进行验证了:

    const filename = fileRef.value.name;
    const ext = filename.split(".").pop();
    

    到这里,一个简单的后缀验证已经实现,但基于后缀进行文件的验证是存在一定隐患的:比如用户刻意更改了文件的后缀。

    【文件上传那些事儿】 - 02 二进制级别的格式验证

    这里用户将 apk 文件后缀改成了 png,随后可见无论是 file.type 还是通过 name 都将其视为了图片,而如果用户在通过前端的验证之后进行抓包改包再次将文件类型改成 apk,就有可能将一个不安全的文件上传到服务器上去了。

    升级版:二进制

    在实现功能之前,我们可以先下一个 winhex 或者直接在 vscode 中装一个 hexdump 来看看不同的文件有什么区别。

    JPG

    【文件上传那些事儿】 - 02 二进制级别的格式验证

    PNG

    【文件上传那些事儿】 - 02 二进制级别的格式验证

    结论

    其他类型也都类似,感兴趣的读者可以自行查看,这里直接上结论:

    • JPG:文件头为 FF D8 FF
    • PNG:文件头为 89 50 4E 47
    • GIF:文件头为 47 49 46 38

    这里我们就以 GIF 为例进行说明。

    首先要封装一个方法,将文件头转成 16 进制编码的格式,细节看注释即可:

    const blobToString = (blob: Blob): Promise<string> => {
      return new Promise(resolve => {
        const reader = new FileReader();
        reader.onload = () => {
          const result = (reader.result as string)
            .split("")
    				// 转化成 asc 码
            .map((v: string) => v.charCodeAt(0))
    				// 转化成 16 进制
            .map((v: number) => v.toString(16))
    				// 补齐 0
            .map((v: string) => v.padStart(2, "0"))
            .join(" ");
          resolve(result);
        };
        reader.readAsBinaryString(blob);
      });
    };
    

    那么如果我们要判断一个文件是否是 GIF,直接将前 4 个字节传进去即可:

    const isGif = async (file: File): Promise<boolean> => {
      const ret = await blobToString(file.slice(0, 4));
      return ret === "47 49 46 38";
    };
    

    现在我们将 png 文件改成 gif 再次测试一下:

    【文件上传那些事儿】 - 02 二进制级别的格式验证

    结束语

    大功告成,现在上传小 demo 已经有了拖拽上传,进度条和文件类型验证的功能,算是初具规模了,之后的文章中,我们将介绍如何实现诸如大文件切片上传,文件秒传以及断点续传等功能。

    那么今天就到此为止,期待下一次的相遇~


    起源地下载网 » 【文件上传那些事儿】 - 02 二进制级别的格式验证

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元