最近在用golang写一个爬取自己邮件信息的功能,由于对电子邮件的各种协议和结构不太了解,走了很多弯路,下面我分享一下从网上学习到电子邮件有关结构的知识:
一封传统的电子邮件结构内容:
- From: “Tim” tim@example.com
- To: “joe Zhang” zhang@example.com
- Subject: Test
- Date: Wed, 17 May 2020 12:02:29 -0400
- Message-ID: NDBBIAKOPKHFGPLCODIGIEKBCHAA.tim@example.com
- body: Hello World.
在结构上,这封信分两个部分:
- 信件头
- 信件内容(body)
符合规范RFC 822。但是协议规定导致:
- 非英语字符都不能在电子邮件中使用;
- 电子邮件中不能插入二进制文件(如图片);
- 电子邮件不能有附件
这导致补充协议 MIME系列诞生。
MIME对传统电子邮件的扩展,表现在它在信件头部分添加了几条语句,主要有三条
-
第一条是:指明这封信使用了MIME规范
MIME-Version: 1.0
-
第二条语句是:它表明传递的信息类型和采用的编码
Content-Type: text/plain; charset=“ISO-8859-1”
Content-Type表明信息类型,缺省值为" text/plain"。它包含了主要类型(primary
type)和次要类型(subtype)两个部分,两者之间用"/"分割。主要类型有9种,分别是application、audio、example、image、message、model、multipart、text、video。
经常使用的有:
-
text/plain:纯文本,文件扩展名.txt text/html:HTML文本,文件扩展名.htm和.html
-
image/jpeg:jpeg格式的图片,文件扩展名.jpg image/gif:GIF格式的图片,文件扩展名.gif
-
audio/x-wave:WAVE格式的音频,文件扩展名.wav audio/mpeg:MP3格式的音频,文件扩展名.mp3
-
video/mpeg:MPEG格式的视频,文件扩展名.mpg
-
application/zip:PK-ZIP格式的压缩文件,文件扩展名.zip
如果信息的主要类型是"text",那还须指明编码类型"charset",缺省值是ASCII,也可能"ISO-8859-1"、“UTF-8”、"GB2312"等
-
MIME规定了第三条语句:
Content-transfer-encoding: base64
举个例子:
邮件的源码:
- Date: Wed, 18 Jun 2008 18:07:51 +0800 (CST)
- From: xxx xxx@163.com
- To: yifeng.ruan@gmail.com
- Message-ID:
14410503.1073611213783671983.JavaMail.coremail@bj163app54.163.com
- Subject: =?gbk?B?xOO6ww==?=
- MIME-Version: 1.0
- Content-Type:
multipart/alternative;boundary="----=_Part_287491_22998031.1213783671982"------=_Part_287491_22998031.1213783671982Content-Type:
text/plain; charset=gbk
- Content-Transfer-Encoding:
base64IAq4+b7dsr+209PQudi55raoo6yyu7XD1Nq12Le9yM66zs341b7Jz7nSz+DTprXEtqvO96Osx+vE49TaxOO1xLKpv83W0AogIArW0Ln6yr2x6tPvIC0gyO7Su7fltcTN+MLnyNXWvgoKtcS12jEy1cXNvMasyb6z/aOst/HU8s7Sw8fXt76/xOO1xM/gudjU8MjOoaPQu9C7us/X96OhtMvNvMas1Nq4vbz+wO/D5g==------=_Part_287491_22998031.1213783671982Content-Type:
text/html; charset=gbk
- Content-Transfer-Encoding: quoted-printable
=B8=F9=BE=DD=B2=BF=B6=D3=D3=D0=B9=D8=B9=E6=B6=A8=A3=AC=B2=BB=B5=C3=D4==DA=B5=D8=B7=BD=C8=CE=BA=CE=CD=F8=D5=BE=C9=CF=B9=D2=CF=E0=D3=A6=B5=C4=B6=AB==CE=F7=A3=AC=C7=EB=C4=E3=D4=DA=C4=E3=B5=C4=B2=A9=BF=CD=D6=D0......
可以看到这封信的MIME语句是:
MIME-Version: 1.0
Content-Type: multipart/alternative;boundary="----=_Part_287491_22998031.1213783671982"
"Content-Type: multipart/alternative;“表明这封信的内容,是纯文本和HTML文本的混合。另两个可能的值是multipart/mixed和multipart/related,分别表示"信件内容中有二进制内容"和"信件带有附件”。
“boundary=”----=_Part_287491_22998031.1213783671982"“表明不同信件内容的分割线是”----=_Part_287491_22998031.1213783671982",它通常是一个很长的随机字符串。
信件内容部分又有两个子信件头:
- Content-Type: text/plain; charset=gbkContent-Transfer-Encoding:
base64 - Content-Type: text/html; charset=gbkContent-Transfer-Encoding:
quoted-printable
它们表明,第一个部分是gbk编码的纯文本,编码转换格式是base64。第二个部分是gbk编码的HTML文本,编码转化格式是quoted-printable。