如何解析EML(邮件)格式的文件以及一款小巧的EML邮件阅读工具

Posted 一只会铲史的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解析EML(邮件)格式的文件以及一款小巧的EML邮件阅读工具相关的知识,希望对你有一定的参考价值。

在理解EML格式的时候,先回顾一下历史,这样有助于理解邮件的格式,比如邮件传输时为何会有多种编码方式。此外,理解EML格式也有助于理解HTTP协议。

历史溯源

由于历史原因,我们目前看到的大部分的网络协议都是基于ASCII码这种纯文本方式,也就是基于字符串的命令行方式,比如HTTP、FTP、POP3、SMTP、TELNET等。
 
早期操作系统比如Unix或DOS没有图形界面,用户与电脑之间只能通过控制台进行交互,也就是通过键盘将命令(或请求)输入到电脑,当用户回车换行(\\r\\n)时,表示命令输入完毕。如果存在网络通信,则该命令包括用户敲击的回车换行会一并发送到服务器端,服务器端接收数据时,就会以回车换行来界定一条完整的命令是否获取完毕,否则会继续等待直到接收到"\\r\\n"或超时,当请求接收完毕后,服务端会执行该请求并将响应结果返回给客户端。
 
理解这一点非常重要,这就是为什么很多网络应用层协议都是以"\\r\\n"来作为结束标记。对于多行请求时,通常以两个连续的回车换行表示请求结束,也就是"\\r\\n\\r\\n",直观的用肉眼观察就是存在一个空行。
比如HTTP协议,与主机建立连接后,输入"GET / HTTP/1.1\\r\\n\\r\\n"即可获取网站的主页。

 
回到Email协议(SMTP和POP3),早期的电子邮件只支持ASCII码这种纯文本传输方式,但随着全世界人民对物质文化生活的不断向往,这种落后的传输方式,已经无法满足世界人民对美好生活的追求,比如图像、视频、音频、Office文件如何在邮件中展现?不同国家(非英语国家)字符集该如何传输和展现?
换句话说,就是这种非ASCII的二进制富文本,该如何传输和呈现?

MIME的诞生

此时MIME标准诞生了,MIME的出现更多的是一种向下兼容的无奈,而不是革命。通过对二进制数据或非ASCII码数据进行base64或quoted-printable编码,来实现纯ASCII码的传输。显然这种方式会让你的邮件体变大,传输效率下降。尤其附件很多时,通过MIME的boundary来解析邮件的附件也是一笔额外的负担。

同时MIME的标准也被HTTP协议所采用,我们可以通过content-type字段指定传输的内容是什么类型,通过MIME的boundary来对Form-Data数据进行扩展,让我们在POST数据时也能够在“表格”数据中插入文件,从而达到上传文件的效果。
 
下面是一个EML格式的文件截图,该截图是一个邮件头,该邮件头包含几个重要字段,Subject(主题),From(发件人)To(接收人),Cc(抄送人),Date(发送日期)。
其中一个最重要的字段就是Content-Type。只有解析了Content-type字段我们才能准确的将邮件体给解析并展现出来。

通过上图我们可以观察到该邮件的内容是一个混合类型,由多个部分组成,Content-type字段中的boundary被用来分割不同的部分。下图显示的是一个邮件的附件文件,该文件类型为pdf。
 

boundary的前缀加上"--"表示新的邮件内容的开始,紧接着为几行MIME头,仔细观察MIME头则会发现,这些字段其实和HTTP协议的头的字段是相同的。空行后则是具体的邮件内容,这些邮件内容的传输编码方式有两种:一种是base64,一种是quoted-printale,当然也可能是未编码。通常情况下,采用quoted-printable方式对html(邮件正文)进行编码,而对于附件文件(比如二进制文件),则采用base64进行编码。
邮件的正文可能有两个:一个是HTML格式,一个是Plain格式。为什么会有两个格式的正文?其实这两个格式展现出来的内容都是一样的,这样做的目的是为了客户端的兼容,早期的的邮件客户端可能无法显示HTML格式,或者对HTML格式的兼容性不是很好,当然喽这也是历史原因造成的。现在的邮件客户端都能显示HTML的正文了。
当邮件结束时,是以"--"+boundary+"--"来标记,也就是给boundary加上前缀"--"和后缀"--"。
通过对MIME格式的分析我们可以看到解析Content-type字段很重要,通过提取boundary并循环查找,就可以解析出不同的邮件体,从而将一封EML格式的电子邮件展现出来。
最后注意一点: MIME头中字符串采用特有的简洁的编码方式,将字符集和编码方式集成到了一起,以"=?"开始,以"?="结束。"=?"后为字符集,紧接着"?"后表示编码方式。B(b)为base64编码,Q(q)为quoted-printable编码。如下图:

 
附:一款小巧的EML邮件阅读工具(不到300K)


以上是关于如何解析EML(邮件)格式的文件以及一款小巧的EML邮件阅读工具的主要内容,如果未能解决你的问题,请参考以下文章

如何解析带有附件和内联图像的 EML 文件并转换为 HTML

如何在 php 中解析 .eml 文件?

从 MIME 消息信息创建 EML 文件

附件名称和文件扩展名在电子邮件 *.eml 中不起作用

`eml` 文件和 RFC822 电子邮件消息有啥区别?

在 C# 中解析 .eml 文件的建议