问题再现
本人最近在做一个项目,项目中有上传图片的功能。上午 PM 提了一个需求,说这里的上传图片只允许 jpg
、png
格式。心想这还不简单,于是我三下五除二,通过判断文件的 type
属性是否是 image/jpeg
或 image/png
进行校验。代码如下:
const allowedFormats = ["image/jpeg", "image/png"]
function onFileChange({ raw }) {
const isAllowedFormats = allowedFormats.includes(raw.type)
if (!isAllowedFormats) {
this.$message.error("图片只能是 JPG 或 PNG 格式!")
return
}
// ...
}
找了几张图片测试了一下,嗯,效果还可以。于是信心满满的提测,但不料很快就收到了 BUG,BUG 单上赫然写着几个大字:
jfif 格式也能上传成功。
jfif ?这是啥玩意,我倒是第一次听说这种格式。
什么是 jfif ?
上网一搜才发现 jfif 也是一种图片存储格式,根据网上的介绍,该格式直接使用 JPEG 标准,但比普通 JPEG 包含较少的数据。它的全称是 JPEG File Interchange Format,翻译过来就是 JPEG 档案交换格式。
于是我通过 FileDesc 网站查看了一下该格式,发现 jfif 格式的 MIME 类型的确是 image/jpeg
,而不是我们以为的 image/jfif
。
于是找 QA 要了一个样本,测试之后发现的确能通过我们的校验。而输出的 type
正是 image/jpeg
格式。
为什么 jfif 输出的 type
是 image/jpeg
? 这就不得不提 MIME 了。
什么是 MIME?
MIME,全称 Multipurpose Internet Mail Extensions,即多用途互联网邮件扩展。是一个用来表示文档、文件或字节流的性质和格式的标准。
MIME 的组成结构非常简单,由类型与子类型两个字符串中间用 /
分隔而组成,即 type/subtype
。type
表示可以被分多个子类的独立类别,subtype
表示细分后的每个类型。
比如:
text/plain
image/jpeg
audio/mpeg
video/mp4
application/javascript
而通过查阅 IETF 官方文档 发现,jfif 明确被规定为 image/jpeg
类型。以下是原文:
RFC 1341MIME: Multipurpose Internet Mail ExtensionsJune 1992
7.5 The Image Content-Type
A Content-Type of "image" indicates that the bodycontains an image. The subtype names the specific image format. These names are case insensitive. Two initial subtypes are "jpeg" for the JPEG format, JFIF encoding, and "gif" for GIF format [GIF].
总结
到这里,我们就明白了:jfif 其实是作为一种 jpg 格式,属于 jpg 的分支。那么被校验为 image/jpeg
其实也是正确的结果。
参考资料: