前一篇 JavaScript与文字编码 中谈到了 MIME,同时联系到<form>
标签的enctype
属性,所以这里做个小小的总结
为什么会有 MIME
MIME 的全称为“Multipurpose Internet Mail Extensions”,中文译为“多用途互联网邮件扩展”,指的是一系列的电子邮件技术规范。它是作为 SMTP(Simple Mail Transfer Protocal) 的一个扩展。因为当初制定 SMTP 协议的时候并没有考虑传输内容可以有非文本内容(即二进制文件),同时制定者也没有考虑到非英语国家使用的文字。可能早期电子邮件的诞生只是为了解决简单信息即文本的问题,取代电报这一传统方式。
MIME 的相关内容
概述
MIME 主要包括以下三部分内容:
- 5 个新的邮件首部字段,它们可包含在原来邮件的首部中。这些字段提供了有关邮件主体的信息
- 定义了许多邮件内容的格式,对多媒体电子邮件的表示方法进行了标准化
- 定义了传送编码,可对任何内容格式进行转换,而不会被邮件系统改变
下面时 MIME 增加的 5 个新的邮件首部的名称及其含义
- MIME-Version:标明 MIME 的版本。现在的版本号为 1.0。若邮件报文中无此项,表明是遵守 SMTP 协议的传统邮件报文,内容仅为 ASCII 字符
- Contetn-Description:这是可读字符串,说明此邮件主题是否是图像、音频或视频
- Content-Id:邮件的唯一标识符
- Content-Transfer-Encoding:在传送时邮件的主体是如何编码的
- Content-Type:说明邮件主体的数据类型和子类型
上述前面三项意思说的很清楚,第四项Content-Transfer-Encoding
的选项有:
- 7 bit
- 8 bit
- binary
- quoted-printab
- base64
其中第一个方案时缺省值,即不用转化的 ASCII 字符。真正常用的是 quoted-printable 和 Base64 ,而 Base64 编码方案上篇博文 JavaScript与文字编码 有详细介绍,而 quoted-printable 限于篇幅有限,这里就不细说,各位童鞋可以谷歌或者翻阅教科书。这里我们重点说说第五项:Content-Type
最重要的 Content-Type 字段
这一邮件首部及其重要,它表明传递的信息类型和采用的编码。
MIME 标准规定该首部值为:内容类型/子类型。下面表格列举了部分基本内容类型及其子类型:
内容类型 | 子类型 | 说明 |
---|---|---|
text | plain、html、xml、css | 不同格式的文本 |
image | gif、jpeg、tiff | 不同格式的图像 |
audio | basic、mpeg | 可听见的声音 |
video | mpeg、mp4、quicktime | 不同格式的影片 |
application | octet-stream、pdf、x-www-form-urlencoded | 不同应用程序产生的数据 |
multipart | mixed、alternative、parallel、digest | 多种类型的组合 |
其中如果内容主体的类型为“text”,那么还必须指明编码类型“charset”,缺省值是 ASCII,其他可能值有 UTF-8、GB2312、GBK 等。还有 MIME 允许自定义内容类型。但为了避免可能出现名字冲突,标准要求自定义的内容类型的名称要以字符串x-
开始。例如 HTML form 标签的 enctype 属性值之一:x-www-form-urlencode
同时还要注意到 MIME 中的 multipart 内容类型,该内容类型很有用,因为它使邮件增加了相当大的灵活性,其子类型主要有:
- mixed——该子类型允许单个报文含有多个相互独立的子报文,每个子报文可有自己的类型和编码,可以是文本、图像或声音。在 mixed 后面还要用到一个关键字,即
Boundary=
,此关键字定义了分割报文各部分所用的字符串,只要在邮件的内容中不会出现这样的字符串即可,可以把它理解为分割标识符。当某一行以两个连字符“–”开始,后面紧跟上述的字符串,就表示下面开始了另一个子报文。 - alternative——该子类型允许单个报文含有同一数据的多种表示。当给多个使用不同硬件平台或软件平台的收件人发送文本时就很有用。比如,用户可同时用普通的 ASCII 文本和格式化的形式发送文本,从而允许拥有图形功能的计算机用户在察看图形时选择格式化的形式。
- parallel——该子类型允许单个报文含有可同时显示的各个子部分。例如,图像和声音同时播放。
- digest——该子类型允许单个报文含有一组其他报文。
HTTP 报文中的实体首部
其实 Content-Type 字段不仅使用在电子邮件,后来也被移植到了 HTTP 协议中。HTTP 报文中的实体首部就有 Content-Type 这一字段,其用来说明报文实体部分的内容类型。
form 标签的 enctype 属性
enctype 属性规定了对表单提交给服务器时表单数据编码的内容类型(Content-Type),这里的“内容类型”就是来自 MIME 的 Content-Type 字段。但是 enctype 属性值只有三种:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
application/x-www-form-urlencoded
form 表单提交的默认内容类型,使用该类型时,会将表单数据组合成key1=value1&key2=value2
形式。其中要注意表单数据中如果有非字母数字的字符,那么该字符会转换。因为 RFC 文档规定 URL 只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号。所以如果 URL 中有汉字,就必须编码后使用。至于怎么编码,各位童鞋可查看阮一峰的 关于URL编码|阮一峰的网络日志。这篇文章虽然距今有点久远,具体方案可能会有所改变,但至少可以让你更加了解 URL 编码的问题。
采用此种内容类型,后端在取数据后,需要进行分解。同时还要注意,若此时表单中有文件,那么表单数据只有文件名。
mulltipart/form-data
该内容类型不对字符编码,在使用包含文件上传控件的表单时,必须使用该值。
text/plain
表单数据中的空格转换为 “+” 加号,但不对特殊字符编码。要注意的是,若表单中有文件,则表单数据仅为文件名。
参考
- MIME笔记|阮一峰的网络日志
- 《计算机网络》谢希仁著(第七版)
- 表单提交时编码类型enctype详解|SegmentFault
- 关于URL编码|阮一峰的网络日志