From : http://hi.baidu.com/gaomanyi/blog/item/b0a3c309b899ed84d0581b2c.html
MIME邮件格式
在RFC 2822文档中定义了简单的 ASCII编码的Email的邮件格式,然而随着Internet的发展,Email邮件仅仅传输简单的文本已经满足不了用户的需求,为了在Email 中传输大量HTML、图像、声音以及各种附件格式,一种新的扩展的邮件格式应运而生——MIME。由于在MIME邮件格式非常复杂,大量的RFC文档中对MIME邮件格式进行了定义与说明,比如RFC2045, RFC2046, RFC2047, RFC2049, RFC2231, RFC2387, RFC4288, RFC4289等。因此,MIME邮件格式为我们提供了极大的灵活性的同时也给我们解读MIME格式的Email邮件带来了极大的困难。以下就一封具体的邮件原始信息对MIME邮件格式作出一个概要的介绍。
解释几个常用且不易理解的Content-Type开头的MIME首部:
Received: from JSJ104 (unknown [202.204.96.147])
by smtp14 (Coremail) with SMTP id wKjRDyJAHALkc2lFEtAjAg==.38990S2;
Sun, 26 Nov 2006 19:00:55 +0800 (CST)
Message-ID: <000601c7114a$2fd50450$9360ccca@JSJ104>
From: <ctp_41023@163.com>
To: <ctp_41023@163.com>
Subject: =?gb2312?B?MTIzMTIzxOO6wzEyMzEyMw==?=
Date: Sun, 26 Nov 2006 19:01:04 +0800
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_NextPart_000_0003_01C7118D.38E01920"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2962
This is a multi-part message in MIME format.
------=_NextPart_000_0003_01C7118D.38E01920
Content-Type: text/plain;
charset="gb2312"
Content-Transfer-Encoding: base64
MTIzMTIzMTIz
------=_NextPart_000_0003_01C7118D.38E01920
Content-Type: text/html;
charset="gb2312"
Content-Transfer-Encoding: base64
PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgaHR0cC1lcXVpdj1Db250ZW50LVR5cGUgY29udGVu
dD0idGV4dC9odG1sOyBjaGFyc2V0PWdiMjMxMiI+DQo8TUVUQSBjb250ZW50PSJNU0hUTUwgNi4w
MC4yOTAwLjI5OTUiIG5hbWU9R0VORVJBVE9SPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+DQo8
Qk9EWSBiZ0NvbG9yPSNmZmZmZmY+DQo8RElWPjxGT05UIHNpemU9Mj4xMjMxMjMxMjM8L0ZPTlQ+
PC9ESVY+PC9CT0RZPjwvSFRNTD4NCg==
------=_NextPart_000_0003_01C7118D.38E01920--
这封Email具有一个邮件首部,然后是邮件的主体部分,它包括一个文本和一个HTML类型。可以注意到这样一行编码“boundary="----=_NextPart_000_0003_01C7118D.38E01920" ”,它是用来隔离MIME邮件的各个实体部分。
在RFC2822中定义了MIME邮件首部的格式:
field-name ":" [ field-body ] CRLF
例如:
MIME-Version: 1.0
Content-Type: multipart/alternative;
Content-Type: text/plain;
Content-Transfer-Encoding: base64
最常见也用途最都的MIME首部是以Content-Type开头的,在RFC2046给出了它的定义,大致与如下内容相似:
Content-Type: text/plain;
Content-Type: text/plain; charset=ISO-8859-1
Content-Type: text/plain; charset=us-ascii
Content-Type: text/plain; charset=utf-8
Content-Type: text/html;
Content-Type: text/html; charset=ISO-8859-1
Content-Type: text/css
Content-Type: image/gif; name=image004.gif
Content-Type: image/jpeg; name="image005.jpg"
Content-Type: message/delivery-status
Content-Type: message/rfc822
Content-Type: audio/x-mpeg
Content-Type: video/mpeg-2
Content-Type: application/msword
Content-Type: application/mspowerpoint
Content-Type: application/zip
Content-Type: multipart/mixed; boundary="----=_Part_3431_12384933.1139387792352"
Content-Type: multipart/alternative; boundary="----=_Part_4088_29304219.1115463798628"
Content-Type: multipart/related; boundary="----=_Part_2067_9241611.1139322711488"
Content-Type: multipart/digest; boundary="----=Next message 15543233913938263541"
Content-Type: multipart/report; report-type=delivery-status;
boundary="k04G6HJ9025016.1136391237/carbon.singnet.com.sg"
Content-Type: multipart/parallel
1) Content-Type: multipart/mixed
它表明这封Email邮件中包含各种格式的MIME实体但没有具体给出每个实体的类型。
2) Content-Type: multipart/alternative
如果同一封Email邮件既以文本格式又以HTML格式发送,那么要使用Content-Type: multipart/alternative。这两种邮件格式实际上是显示同样的内容但是具有不同的编码。
3) Content-Type: multipart/related
用于在同一封邮件中发送HTML文本和图像或者是其他类似类型。
邮件主体的编码:
主要是包括quoted-printable与base64两种类型的编码。Base64和Quoted-Printable都属于MIME(多用途部分、多媒体电子邮件和 WWW 超文本)的一种编码标准,用于传送诸如图形、声音和传真等非文本数据)。
一.Base64
Base64是现今在互联网上应用最多的一种编码,绝大多数的电子邮件软件头把它作为默认的二进制编码,比如我们常用的Outlook。
Base64内容传输编码被设计用于以人无法可读的方式来表述八位组的任意序列。编码与解码算法很简单,但是编码数据总是比非编码数据长33%。这种编码实际上类似于RFC1421中定义的在增强保密邮件(PEM)应用程序中使用的编码方式。
编码程序将字符流顺序放入一个 24 位的缓冲区,缺字符的地方补零。从左到右,一个24位输入组通过级联3个八位输入组组成。随后这24位截断成为 4 个部分,每个部分 6 位,分别被翻译为base64字母表中的一个单独数字。当通过Base64编码一个位流时,位流必须假设为以最高有效位优先的顺序排列。也就是说,流中的第一位将是第一字节中的高端位,而第八位则位第一字节中的低端字节位。
如果输入数据不足24个字符,即只有一个或两个字节时,则需要经过特殊处理——在数据末尾填充"="字符,这可以隔断附加的信息造成编码的混乱。
在Base64编码数据中,任何在Base64字母表之外的字符将被忽略。Base64编码中的非法字符序列也将被忽略,例如"=====".
二.Quoted-Printable
Quoted-Printable与Base64一样,常常用在Email系统中。它通常用于少量文本方式的8位字符的编码,例如Foxmail就用它做对主题和信体的编码。这种编码的应该是很好辨认的:它有大量的'='。
QP的算法非常的简单但是编码效率很低(1:3),它是专门为了处理8位字符制定的。它的算法是:读一个字符,如果ASCII码大于127,即字符的第8位是1的话,进行编码,否则忽略(有时也对7位字符编码)。
参考资料:
http://biancheng.dnbcw.info/perl/251301.html
一、MIME: Multipurpose Internet Mail Extensions
http://www.cis.ohio-state.edu/hypertext/faq/usenet/mail/mime-faq/mime0/faq.html
MIME提供了一种可以在邮件中附加多种不同编码文件的方法,弥补了原来的信息格式的不足。实际上不仅仅是邮件编码,现在MIME经成为HTTP协议标准的一个部分。
其编码的方法是,将输入数据流每次取6bit,用此6bit的值(0-63)作为索引去查表,输出相应字符。
这样,每3个字节将编码为4个字符(3×8 → 4×6);不满4个字符的以'='填充。
有的场合,以“=?charset?B?xxxxxxxx?=”表示xxxxxxxx是Base64编码,且原文的字符集是charset。在段体内则直接编码,适当时机换行,MIME建议每行最多76个字符。
Base64的算法很简单,它将字符流顺序放入一个24位的缓冲区,缺字符的地方补零。
然后将缓冲区截断成为4个部分,高位在先,每个部分6位,用64个字符重新表示。如果输入只有一个或两个字节,那么输出将用等号“=”补足。这可以隔断附加的信息造成编码的混乱。
Quoted -printable根据输入的字符串或字节范围进行编码,若是不需编码的字符,直接输出。若需要编码,则先输出'=',后面跟着以2个字符表示的十六进制字节值。有的场合,以“=?charset?Q?xxxxxxxx?=”表示xxxxxxxx是Quoted-printable编码,且原文的字符集是charset。在段体内则直接编码,适当时机换行,换行前额外输出一个'='。
三、MIME的头信息
Received 传输路径 各级邮件 服务器
Return-Path 回复地址 目标邮件 服务器
Delivered-To 发送地址 目标邮件服务器
Reply-To 回复地址 邮件的创建者
From 发件人地址 邮件的创建者
To 收件人地址 邮件的创建者
Cc 抄送地址 邮件的创建者
Bcc 暗送地址 邮件的创建者
Date 日期和时间 邮件的创建者
Subject 主题 邮件的创建者
Message-ID 消息ID 邮件的创建者
MIME-Version MIME版本 邮件的创建者
Content-Type 内容的类型 邮件的创建者
Content-Transfer-Encoding 内容的传输编码方式 邮件的创建者
Content-Type 段体的类型
Content-Transfer-Encoding 段体的传输编码方式
Content-Disposition 段体的安排方式
Content-ID 段体的ID
Content-Location 段体的位置(路径)
Content-Base 段体的基位置
表示使用的MIME的版本号,一般是1.0;
如:
MIME-Version: 1.0
text charset 字符集
image name 名称
application name 名称
multipart boundary 边界
multipart类型表示正文是由多个部分组成的,后面的子类型说明的是这些部分之间的关系。
邮件中用到的三个类型有:
(1).multipart/alternative:表示正文由两个部分组成,可以选择其中的任意一个。主要作用是在征文同时有text格式和html格式时,可以在两个正文中选择一个来显示,支持 html 格式的邮件客户端软件一般会显示其 HTML 正文,而不支持的则会显示其Text正文;
(2).multipart/mixed:表示文档的多个部分是混合的,指正文与附件的关系。如果邮件的MIME类型是multipart/mixed,即表示邮件带有附件。
(3).multipart/related:表示文档的多个部分是相关的,一般用来描述 Html 正文与其相关的图片。
| |
| +----------------- multipart/related ------------------+ |
| | | |
| | +----- multipart/alternative ------+ +----------+ | +------+ |
| | | | | 内嵌资源 | | | 附件 | |
| | | +------------+ +------------+ | +----------+ | +------+ |
| | | | 纯文本正文 | | 超文本正文 | | | |
| | | +------------+ +------------+ | +----------+ | +------+ |
| | | | | 内嵌资源 | | | 附件 | |
| | +----------------------------------+ +----------+ | +------+ |
| | | |
| +------------------------------------------------------+ |
| |
+----------------------------------------------------------------------+
可以看出,如果在邮件中要添加附件,必须定义multipart/mixed段;如果存在内嵌资源,至少要定义multipart/related段;如果纯文本与超文本共存,至少要定义multipart/alternative段。什么是“至少”?举个例子说,如果只有纯文本与超文本正文,那么在邮件头中将类型扩大化,定义为multipart/related,甚至multipart/mixed,都是允许的。
含有 MIME/BASE64编码的邮件,你查看它的源码时一般都含有:“This is a multi-part message in MIME format.”这样的句子。也可以被绝大多数的email程序进行解码,包括Netscape、MS Mail、Eudora等。这些程序可以正确识别邮件的正文,恢 MIME/BASE64 编码的部分为正确的文字或夹带的二进制文件。
Content-Transfer-Encoding共有Base64, Quoted-printable, 7bit, 8bit, Binary等几种。
其中7bit是缺省的编码方式。电子邮件源码最初设计为全部是可打印的ASCII码的形式。
非ASCII码的文本或数据要编码成要求的格式。
Base64, Quoted-Printable是在非英语国家使用最广使的编码方式。
Binary方式只具有象征意义,而没有任何实用价值。