由<input type="file" />获取的file.type为空字符串引申浏览器是如何获取文件的MIME类型

前言

  今天项目上遇到了一个问题,用户需要导入一个从我们服务器上下载的EXCEL文件,前端根据获取到的文件的type属性进行判断是否可以上传["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-excel"],但是在某一个用户的电脑上却出现了通过<input type="file">获取到的file对象中,type属性为"",于是开始找各种资料希望了解浏览器是如何获取这个type属性的,为什么同一个文件不同的电脑获取到的属性不一样。

MIME Type是什么

  根据MDN上的说明,MIME Type (Multipurpose Internet Mail Extensions (MIME) type)是一种标准化的方式来表示文档的性质和格式。它在IETF RFC 6838中进行了定义和标准化。
  浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理文档;因此服务器设置正确以将正确的MIME类型附加到响应对象的头部是非常重要的。所以浏览器中<input type="file">获取到的file对象中的type属性其实是文件的MIME Type。

Chrome获取MIME类型

  在chromium开源代码中 https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=314 314-318行中提到了:

  // We implement the same algorithm as Mozilla for mapping a file extension to
  // a mime type.  That is, we first check a hard-coded list (that cannot be
  // overridden), and then if not found there, we defer to the system registry.
  // Finally, we scan a secondary hard-coded list to catch types that we can
  // deduce but that we also want to allow the OS to override.

  Chrome实现了与Mozilla相同的算法,将文件扩展名映射到MIME类型。
首先,Chrome会检测一个硬编码列表(不能被覆盖)源码中的kPrimaryMappings,然后如果没有找到符合的,Chrome会从操作系统注册表中找,最后会扫描一个二级硬编码列表,源码中的kSecondaryMappings,用来捕获可以推断但是也希望允许操作系统覆盖的类型。
  例如:从安装了Microsoft Excel的Windows系统上传CSV文件时,Chrome会将其报告为application/vnd.ms-excel。这是因为.csv未在第一个硬编码列表中指定,因此浏览器会回退到系统注册表。HKEY_CLASSES_ROOT\.csv有一个名为的值Content Type设置为application/vnd.ms-excel

总结

  前言中遇到的问题浏览器中获取不到type属性不一定是代码的原因,而是系统中所安装的Microsoft Excel软件或注册表的原因,另外在MDN中的File对象中也找到这也一句描述:基于当前的实现,浏览器不会实际读取文件的字节流,来判断它的媒体类型。它基于文件扩展来假设;重命名为 .txt 的 PNG 图像文件为 "text/plain" 而不是 "image/png" 。而且,file.type 仅仅对常见文件类型可靠。例如图像、文档、音频和视频。不常见的文件扩展名会返回空字符串。开发者最好不要依靠这个属性,作为唯一的验证方案。

182 声望
5 粉丝
0 条评论
推荐阅读
CentOS7 下安装 Mysql 8
MySQL Yum存储库提供了一种使用Yum使用最新软件包安装和更新MySQL产品的简单方便的方法。您可以根据我的步骤进行安装,也可以查看官方快速指南查找不同系统环境的安装方式。

拂晓弄尘影3阅读 2.4k

CSS transition 小技巧!如何保留 hover 的状态?
欢迎关注我的公众号:前端侦探通常情况下,hover 是无法保存状态的。鼠标移入触发额外样式,一旦移出就还原了 {代码...} 这就意味着,如果需要保留hover的状态,可能就不得不借助JS了,比如下面是某某书院的首页...

XboxYan29阅读 3.6k评论 2

封面图
现代 CSS 之高阶图片渐隐消失术
在过往,我们想要实现一个图片的渐隐消失。最常见的莫过于整体透明度的变化,像是这样: {代码...} {代码...} 但是,CSS 的功能如此强大的今天。我们可以利用 CSS 实现的渐隐效果已经不再是如此的简单。想想看,...

chokcoco27阅读 2.1k

封面图
给我实现一个前端的 Excel 导入和导出功能
前言【负责人 A】:现在报表部分基于接口的 Excel 的导入和导出功能有点慢,前端这边能不能实现一下这个功能,然后我们在比对看看效果!【切图仔 B】: 接口这边不能优化一下吗?比如排查下慢的原因什么的。【负...

熊的猫19阅读 2.6k

封面图
开局一张图,构建神奇的 CSS 效果
假设,我们有这样一张 Gif 图:利用 CSS,我们尝试来搞一些事情。图片的 Glitch Art 风在这篇文章中 --CSS 故障艺术,我们介绍了利用混合模式制作一种晕眩感觉的视觉效果。有点类似于抖音的 LOGO。像是这样:假设...

chokcoco13阅读 2.1k评论 3

封面图
你知道前端水印功能是怎么实现的吗?
前一段时间由于项目需要实现水印功能,于是去了解了相关的内容后,基于 Vue 的实现了一个 v-watermark 指令完成了对应的功能,其实整体内容并不复杂!

熊的猫14阅读 1.7k

封面图
现代 CSS 高阶技巧,完美的波浪进度条效果!
本文为稀土掘金技术社区首发签约文章,14 天内禁止转载,14 天后未获授权禁止转载,侵权必究!我的新的专栏 -- 现代 CSS 与 Web 动画解决方案。将专注于实现复杂布局,兼容设备差异,制作酷炫动画,制作复杂交互...

chokcoco10阅读 2.7k

封面图
182 声望
5 粉丝
宣传栏