← 全部工具

MIME 类型参考

了解 MIME 类型是什么、type/subtype 格式如何运作、Content-Type 在 HTTP 和邮件中的重要性、常见类型及设错的后果。
扩展名MIME 类型

MIME 类型究竟是什么

MIME 类型,也称为媒体类型(media type),是一个简短的标签,用来告诉软件某个文件或消息正文包含哪种数据。它诞生于电子邮件(这个名字代表多用途互联网邮件扩展,Multipurpose Internet Mail Extensions),但如今它在网络上无处不在。其格式始终是 type/subtype:一个大类、一个斜杠,以及一个具体格式。所以 text/html 表示"文本,以 HTML 形式",image/png 表示"一张图像,以 PNG 形式",而 application/json 表示"应用程序数据,以 JSON 编码"。

顶级的类型来自官方注册机构 IANA 维护的一个固定集合:textimageaudiovideoapplicationfontmodelmultipart,以及一些较新的类型如 haptics子类型则是具体的格式。厂商可以用 vnd. 前缀添加自己的子类型(例如 application/vnd.ms-excel),而实验性类型在历史上曾使用 x- 前缀,不过这一惯例现已不被提倡。

抽象的发光文件格式图标在深靛蓝背景上被归入带标签的分类方块中
每一种文件格式都对应一个 type/subtype 标签。

MIME 类型在哪里重要

MIME 类型出现的最重要的位置是 HTTP 的 Content-Type 响应头。当服务器发送一个页面、一张图像或一个 API 载荷时,这个头告诉浏览器如何解读这些字节。如果头说 text/html,浏览器就渲染标记;如果说 application/jsonfetch() 调用就能解析它;如果说 application/pdf,内置查看器就会打开。同样的头在请求端也会出现:当你 POST 一个表单或 API 正文时,Content-Type 告诉服务器如何读取你发送的内容。

除了 HTTP,MIME 类型还驱动着其他几套系统。电子邮件客户端用它来决定附件是该预览的图像还是该保存的二进制文件。文件上传处理程序检查所声明的类型来接受或拒绝文件。操作系统或浏览器则使用类型而不仅仅是文件扩展名来选择默认应用程序。同样的理念也支撑着服务器如何连同 HTTP 状态码一起报告结果和错误——一个类型错误的 200 响应,可能和 404 一样糟糕。

你每天都会用到的那些

少数几种类型涵盖了真实流量中的绝大部分:

  • text/html——网页(扩展名 .html
  • text/css——样式表(.css
  • text/javascript——JavaScript 的推荐类型(.js.mjs
  • application/json——唯一官方的 JSON 类型,定义于 RFC 8259(.json
  • image/pngimage/jpegimage/webpimage/svg+xml——常见的图像格式
  • application/pdf——PDF 文档(.pdf
  • application/octet-stream——用于未知或任意二进制数据的万能类型
  • text/plain——没有更丰富类型的纯文本的默认值

JSON 值得一提,因为它常让人犯错。唯一正确的类型是 application/json。旧代码有时使用 text/jsontext/plainapplication/x-javascript,但这些都已过时,有些客户端会拒绝解析它们。JSON 也没有字符集参数——规范强制使用 UTF-8,所以写成 application/json; charset=utf-8 是多余的,尽管无害。要查看更完整的格式与扩展名对照表,请参阅我们的参考表

一个发光的数据包带着一个抽象的类型徽章在网络连接中流动
Content-Type 随载荷一起通过 HTTP 传输。

为什么错误的 Content-Type 会出问题

浏览器和客户端信任所声明的类型,因此搞错它会带来具体的后果。把一个 JSON API 响应作为 text/html 发送,浏览器可能会试图渲染它,或者一个严格的客户端会在你的代码运行之前就抛出解析错误。把一个 CSS 或 JavaScript 文件以错误的类型发送,一项名为 X-Content-Type-Options: nosniff 的安全特性会让浏览器拒绝应用它,悄无声息地破坏你页面的样式或脚本。

下载是另一个经典的失败场景。如果你想让文件被下载而不是显示,类型与 Content-Disposition 头同样重要。一个以 application/octet-stream 发送的 PDF 会作为通用文件下载,而不是在查看器中打开;一张以 text/plain 发送的图像会显示为乱码字符。在上传端,一个标签错误的文件可能轻松绕过一个幼稚的扩展名检查,这也是为什么健壮的验证器会检查真实的字节(即"魔数"),而不是信任客户端提供的类型。

从历史上看,当头看起来有误时,浏览器会试图猜测或"嗅探"(sniff)真实类型。这种行为造成了安全漏洞,所以现代的最佳实践是始终发送准确的 Content-Type 并用 nosniff 禁用嗅探。简而言之:在每个响应上有意地设置类型,大多数渲染、下载和解析的问题就会消失。

常见问题

MIME 类型和媒体类型有什么区别?

它们是同一回事。"MIME 类型"是来自电子邮件的旧称,而"媒体类型"是 IANA 和现代 HTTP 规范更倾向使用的术语。两者都指的是 type/subtype 标签。

JSON 的正确 MIME 类型是什么?

是 application/json,定义于 RFC 8259。诸如 text/json 或 application/x-javascript 之类的旧选项已经过时,有些客户端会拒绝它们。

application/octet-stream 是什么意思?

它是用于任意二进制数据的通用类型,没有更具体的标签。服务器把它用作未知文件类型的后备,这通常会触发下载而不是在浏览器内显示。

为什么我的 CSS 或 JavaScript 文件加载不出来?

通常是服务器以错误的 Content-Type 发送了它。在 X-Content-Type-Options 设为 nosniff 的情况下,浏览器会拒绝应用不是 text/css 的 CSS,或不是 JavaScript 类型的脚本。请修正服务器配置,使其发送正确的类型。

我能给 MIME 类型添加字符集吗?

可以,对于文本格式,使用诸如 text/html; charset=utf-8 之类的参数。对于 JSON 则没有必要,因为按规范该格式始终是 UTF-8,不过添加它也无妨。

文件扩展名决定 MIME 类型吗?

在 HTTP 上不是。服务器决定发送哪种 Content-Type,而浏览器信任那个头。当没有提供明确类型时,扩展名只对工具和操作系统起提示作用。