省流量,先说结论:前端无法通过现有API获取文件真实格式,必须拿到文件的二进制内容,然后和文件规范定义比对,才能得到真实的文件格式。

背景

前端经常会有图片上传的业务需求,例如下图的的需求,要求上传的图片的格式为PNG

在前端,常规的文件上传处理方式是

<form action="uploadFile.do" enctype="multipart/form-data" type="post" ><input type="file" onchange=""><input type="submit">
</form>

如果要限制文件格式为PNG那就很简单,只需修改其 input 标签的 accpet 属性限制可接受的文件类型,代码如下

<input type="file" accept=".png"/>

参考:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers

问题

但,这并不能真正的解决问题,accpet 只是限制了用户选择的文件后缀名,这个特性依赖于浏览器的具体实现,而且用户还可以强制修改上传文件框中的文件类型

另外“聪明”的用户会总直接修改文件后缀名。比如把 logo.jpg 修改为 logo.png

所以,我们需要更进一步的判断,一般来说我们都是从 <input> 元素的 files 属性中取得用户准备上传的文件 FileList 其中的每一个File对象都有type 属性,是这个文件的mime类型,如下图

但不幸的是,这个mime的值,目前浏览器的实现是文件扩展来假设的,当客户强制修改后缀名(上图即是将ico文件修改为了png文件),或者没有拿到后缀名(下图),这个mime也是不准确的

要想知道用户上传的文件真实格式,还得再进一步。

解决方案

既然从浏览器的对象中都无法获取到真实的文件类型,那我们再进一步,把文件的二进制内容读出来,按照规范去比对。

因为之前需求中常用的就是 png、jpg、先查阅文件的定义

  • PNG Specification, Version 1.2
  • JPEG_File_Interchange_Format
  • ICO_(file_format)
/*** 真实文件格式(前4个字节)*/
export const ImgExt2Hex = {'jpg': ['ffd8ffe0', 'ffd8ffe1', 'ffd8ffe2', 'ffd8ffe3'],'png': ['89504e47'],'ico': ['100'],
}

定义检测函数

/*** 检测图片是否是预期的类型* @param {File} imgFile 图片文件对象* @param {string} imgExt 文件预期真实类型* @return {boolean} 文件类型是否和预期一致*/
export const vaildImageType = (imgFile, imgExt) => {const FR = new FileReader;return new Promise((reslove) => {FR.onload = (e) => {const { type } = imgFile;const correctExtHex = ImgExt2Hex[imgExt];let af = e.target.result, view = new DataView(af), first4Byte = view.getUint32(0, false) // 获取32bit数, hexValue = Number(first4Byte).toString(16);if (!type || !correctExtHex) {return reslove(false)}return reslove(correctExtHex.indexOf(hexValue) > -1);}FR.readAsArrayBuffer(imgFile);})
}

使用示例(React) await vaildImageType(file, data.type)

handleChange = async (e) => {const { data, type } = this.propsconst file = e.target.files[0]if (!await vaildImageType(file, data.type)) {return ; //  图片格式不正确}
}

后记

如上,已经简单解决了文件上传业务中图片格式的判断,可能单从文件头4个字节来判断并不是十分准确,但是结合文件后缀+文件头判断,基本可以在业务场景中处理 99.9%的格式问题了。

但这件事还可以继续深入,继续拓展功能,例如下面列出的,以及将这些功能集成到一个npm包里去(看大家的需求了 ;-p)

  • 常用图片、文件格式支持(webp、bmp、tiff、psd、ico)
  • 图片其他属性的读取(尺寸、extif)
  • ico 文件内部所有图片资源尺寸、内容读取

return view前端怎么获取_前端判断上传图片格式相关推荐

  1. java 判断图片格式_Java判断上传图片格式的实例代码

    先给大家介绍下java判断上传图片格式. 由于客户上传图片将png的图片的后缀名改为jpg,所以通过后缀名判断不行,用下面这个方法可以 //判断是否是JPG格式 log.info("-1-- ...

  2. 前端JS获取图片文件的真实格式

    目录 常见方式判断图片格式 图像数据简单说明 JS读取图片真实格式 svg格式的判断 总结 前面博文有提到,当前主流浏览器能支持的图片格式,是七种:jpg.png.gif.bmp.ico.webp.s ...

  3. 前端实习生笔试_前端面试实习题目总结:

    以下是部分整理,有时间还会整理出其他的~~ (最近还在找实习呜呜~~) 1.JavaScript是一种弱类型语言,有什么优点和缺点 https://blog.csdn.net/sinolze... ( ...

  4. java后端与前端的交互_前端和后端数据交互的基本知识和常见方式

    一.首先了解前端,后端,数据三者的关系. 1.前端常常是是html,css,js三者的构成的页面的总称.运行在客户端.以浏览器为例. 2.后端常常是后端语言.比如php,java等写的一些脚本.来操作 ...

  5. java和前端哪个好学_前端好学还是Java好学?

    学web前端 首先要了解前端是做什么的,web前端开发工程师,主要职责是利用 html,css,JavaScript,Flash等各种web技术进行客户端产品的开发.完成客户端程序(也就是浏览器端)的 ...

  6. mysql前端还是后端_前端和后端哪个发展好点?

    前端和后端哪个工资高,哪个发展前景好?事实上,两个都是属于技术研发岗位,都是高薪有前途的职业,不存在说哪个工资更高些,都基本在一万到五万之间,工资的差别主要体现在个人技术上.要问做前端好还是做后端好? ...

  7. return view前端怎么获取_Web 前端路由原理解析和功能实现

    ↑ 点击上面 "时代Java"关注我们, 关注新技术,学习新知识! 什么是前端路由? 路由的概念来源于服务端,在服务端中路由描述的是 URL 与处理函数之间的映射关系. 在 Web ...

  8. 前端切换视图_前端架构 101(五):从 Flux 进化到 Model-View-Presenter

    李熠:前端架构 101(一):在谈论它们之前我们需要达成的共识​zhuanlan.zhihu.com 李熠:前端架构 101(二): MVC 初探​zhuanlan.zhihu.com 李熠:前端架构 ...

  9. bootscripttable前端排序无效_前端你应该知道的八条bug分享给你们

    1: 为什么列表的数据不要让后端同学返回对象, 而应该返回数组? 返回对象我们前端直接遍历有没问题啊, 可以正常显示,那是因为你没有遇到下面描述的情况 bug现象1: 「我明明把3这个key定义在了第 ...

最新文章

  1. 使用NPOI操作Excel
  2. 统计学习基础:数据挖掘、推理和预测_数据挖掘——智能财务进阶之梯(含视频、PPT)...
  3. Navicat Monitor v1.7的新功能说明
  4. 修改android virtual device路径
  5. 转成数组_JavaScript之数组扁平化
  6. python基本概念_python基本概念-关键要素
  7. KNN算法——分类部分
  8. day30 java的IO流(3)
  9. webots python e-puck 集群通信案例
  10. 打开Excle出现配置进度解决方法
  11. 哈希表冲突及处理冲突的方法
  12. echarts-gl三维展示自定义地图
  13. RK3288 开发板 排插物理引脚对应图以及如何进入android6.0.1内核终端、uboot终端
  14. 塞班游戏,钻石狂潮。
  15. 排列组合Cnm的计算公式
  16. 2022级东南大学935计算机考研经验分享
  17. 从JavaScript到TypeScript,Pt。 IIB:使用类,接口和混合器进行设计
  18. 如何用计算机进行绘画,如何在电脑上画画
  19. 北京社保定点医院查询
  20. 黑板报首期(080527)优秀文章推荐

热门文章

  1. python网络编程—TCP协议(二)
  2. 深度学习arm MMU一篇就够了
  3. 防止Stack smash的技术
  4. [How TO]-python venv虚拟环境
  5. 【Prometheus 】 Blackbox_exporter 指标 probe_http_duration_seconds
  6. 1.16 static关键字(静态变量和静态方法)
  7. 1067 Sort with Swap(0, i) (25 分)【难度: 中 / 知识点: 置换群】
  8. 1059 Prime Factors (25 分)【难度: 一般 / 知识点: 分解质因子 】
  9. 双端队列【deque】的常见用法
  10. MySQL使用CREATE INDEX创建索引