• MIME邮件格式分析及信息提取    摘 要 MIME是目前互联网邮件普遍采用的格式标准,本文通过对MIME邮件格式规范的分析和说明,给出了从邮件中提取其所含各种信息的基本方法。  关键词 MIME、...

    MIME邮件格式分析及信息提取

     

         摘   要   MIME是目前互联网邮件普遍采用的格式标准,本文通过对MIME邮件格式规范的分析和说明,给出了从邮件中提取其所含各种信息的基本方法。

        关键词   MIME、邮件、格式、信息提取

     


        MIME,英文全称为“Multipurpose Internet Mail Extensions”,即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范。在MIME出现之前,互联网电子邮件主要遵循由RFC 822所制定的标准,电子邮件一般只用来传递基本的ASCII码文本信息,MIME在 RFC 822的基础上对电子邮件规范做了大量的扩展,引入了新的格式规范和编码方式,在MIME的支持下,图像、声音、动画等二进制文件都可方便的通过电子邮件来进行传递,极大地丰富了电子邮件的功能。目前互联网上使用的基本都是遵循MIME规范的电子邮件。

        电子邮件的分析和读取一般都通过专用的邮件软件来实现,比如Outlook、Foxmail,但这种第三方软件无法和开发者自己的系统整合,通过对MIME邮件格式的分析,我们可以在自己的应用程序中实现对MIME邮件所含信息的读取。

    1   MIME邮件格式分析

        MIME技术规范的完整内容由RFC 2045-2049定义,包括了信息格式、媒体类型、编码方式等各方面的内容,这里我们只介绍其中的一些关键的格式和规范,通过了解这些格式规范,我们就可以实现以编程的方式从MIME邮件中提取基本的邮件信息。

    1.1 域

        MIME邮件的基本信息、格式信息、编码方式等重要内容都记录在邮件内的各种域中,域的基本格式:{域名}:{内容},域由域名后面跟“:”再加上域的信息内容构成,一条域在邮件中占一行或者多行,域的首行左侧不能有空白字符,比如空格或者制表符,占用多行的域其后续行则必须以空白字符开头。域的信息内容中还可以包含属性,属性之间以“;”分隔,属性的格式如下:{属性名称}=”{属性值}”。

        表1是一封示例邮件的内容,其中行1-5、行8都是单行的域,行6-7则是一个多行的域,并带有一个名为charset的属性,属性值为us-ascii。

     

    表1 示例电子邮件

    行1 From: ”suntao” <suntao@fimmu.com>

    行2 To: <yxj@fimmu.com>

    行3 Subject: hello world

    行4 Date: Mon, 9 Oct 2006 16:51:34 +0800

    行5 MIME-Version: 1.0

    行6 Content-Type: text/plain;

    行7             charset="us-ascii"

    行8 Date: Mon, 9 Oct 2006 16:48:25 +0800

    行9

    行10 Hello world

    行11

        邮件规范中定义了大量域,分别用来存储同邮件相关的各种信息,比如发件人的名字和邮件地址信息存储在From域中,收件人的邮件地址信息存储在To域中,开发人员可通过查询RFC文档得到完整的邮件域定义列表。

    1.2   Content-Type域

        Content-Type域定义了邮件中所含各种内容的类型以及相关属性。邮件所含的文本、超文本、附件等信息都按照对应Content-Type域所指定的媒体类型、存储位置、编码方式等信息存储在邮件中。 Content-Type域基本格式:Content-Type:{主类型}/{子类型}。

    示例邮件中的行6-7就是一个Content-Type域,主类型为text,子类型为plain,字符集属性为us-ascii。

    表2:MIME邮件中常见的主类型

    主类型

    常见属性

    参数含义

    text

    charset

    文本信息所使用的字符集

    image

    name

    图像的名称

    application

    name

    应用程序的名称

    multipart

    boundary

    邮件分段边界标识

    1.3   multipart类型

        MIME邮件中各种不同类型的内容是分段存储的,各个段的排列方式、位置信息都通过Content-Type域的multipart类型来定义。multipart类型主要有三种子类型:mixed、alternative、related。

    1.3.1   multipart类型基本格式

         ●   multipart/mixed类型

        如果一封邮件中含有附件,那邮件的Content-Type域中必须定义multipart/mixed类型,邮件通过multipart/mixed类型中定义的boundary标识将附件内容同邮件其它内容分成不同的段。基本格式如下:

    Content-Type: multipart/mixed;

                        boundary="{分段标识}"

         ●   multipart/alternative类型

        MIME邮件可以传送超文本内容,但出于兼容性的考虑,一般在发送超文本格式内容的同时会同时发送一个纯文本内容的副本,如果邮件中同时存在纯文本和超文本内容,则邮件需要在Content-Type域中定义 multipart/alternative类型,邮件通过其boundary中的分段标识将纯文本、超文本和邮件的其它内容分成不同的段。基本格式如下:

    Content-Type: multipart/alternative;

                        boundary="{分段标识}"

         ●   multipart/related类型

        MIME邮件中除了可以携带各种附件外,还可以将其它内容以内嵌资源的方式存储在邮件中。比如我们在发送html格式的邮件内容时,可能使用图像作为html的背景,html文本会被存储在 alternative段中,而作为背景的图像则会存储在multipart/related类型定义的段中。基本格式如下:

    Content-Type: multipart/related;

                        type="multipart/alternative";

                        boundary="{分段标识}"

    1.3.2   multipart类型的boundary属性

        multipart的子类型中都定义了各自的 boundary属性,邮件使用这些boundary中定义的字符串作为标识,将邮件内容分成不同的段,段体内的每个子段以“--”+boundary行开始,父段则以“--”+boundary+“--”行结束,不同段之间用空行分隔。

    1.3.3   multipart类型的层次关系

    表3:multipart子类型之间的层次关系

    Multipart/mixed

    Multipart/related

    Multipart/alternative

    纯文本正文

    超文本正文

     

    内嵌资源

     

    附件

        MIME邮件通过多个Content-Type域的multipart类型将内容分成不同的段,这些段在邮件中不是线形顺序排列的,而是存在一个互相包含的层次关系,multipart子类型之间的层次关系结构如表3。

    1.4   Content-Transfer-Encoding域

        MIME邮件可以传送图像、声音、视频以及附件,这些非 ASCII码的数据都是通过一定的编码规则进行转换后附着在邮件中进行传递的。编码方式存储在邮件的Content-Transfer-Encoding 域中,一封邮件中可能有多个Content-Transfer-Encoding域,分别对应邮件不同部分内容的编码方式。目前MIME邮件中的数据编码普遍采用Base64编码或Quoted-printable编码来实现。

    1.4.1   Base64编码

        Base64编码的目的是将输入的数据全部转换成由64 个指定ASCII字符组成的字符序列, 这64个字符由{'A'-'Z', 'a'-'z', '0'-'9', '+', '/'}构成。编码时将需要转换的数据每次取出6bit,然后将其转换成十进制数字,这个数字的范围最小为0,最大为63,然后查询{'A'-'Z', 'a'-'z', '0'-'9', '+', '/'}构成的字典表,输出对应位置的ASCII码字符,这样每3个字节的数据内容会被转换成4个字典中的ASCII码字符,当转换到数据末尾不足3个字节时,则用“=”来填充。

    1.4.2   Quoted-printable编码

        Quoted-printable编码的目的也是将输入的信息转换成可打印的ASCII码字符,但它是根据信息的内容来决定是否进行编码,如果读入的字节处于33-60、62-126范围内的,这些都是可直接打印的ASCII字符,则直接输出,如果不是,则将该字节分为两个4bit,每个用一个16进制数字来表示,然后在前面加“=”,这样每个需要编码的字节会被转换成三个字符来表示。

    2   MIME邮件信息提取

        从上面的分析可以看出,MIME邮件传递的实际是一个经过特殊编码并以约定格式排列的字符序列,我们只需要提取存储在邮件各种域中的格式、位置和编码信息,按照根据这些信息从字符序列中提取出对应的字符内容并对其进行反向解码,就可以得到我们需要的有关内容。

    下面给出.Net环境下,利用C#结合正则表达式从邮件中提取相关信息的基本思路和部分代码。

    2.1 收件人/发件人/邮件主题的提取

        收件人、发件人、邮件主题是一封邮件的基本组成信息,分别存邮件的From域、To域、Subject域中。开发中只需要通过正则表达式来匹配这些指定的域,然后从匹配结果中取出相关信息即可。

        示例代码:提取邮件主题

    string emailContent = “……”;//emailContent中存储的是邮件内容

    pat = @"^Subject:\s*(?<title>.*)\s*\r\n";

    myMatches = Regex.Matches(emailContent,pat,RegexOptions.Multiline);

    foreach(Match nextMatch in myMatches)

    {

              GroupCollection myGroup = nextMatch.Groups;

              string title = myGroup["title"].ToString();//title变量存储From域的内容

              ……

    }

        需要注意的是上面的代码提取的是跟随在Subject:后面的字符串,如果邮件的主题内容是中文或者其它需要编码的地区文字,则还需要对其进行解码。比如,如果邮件的Subject域中的信息是“你好”,那么提取出来的字符串会是这种形式:=?gb2312?B?xOO6ww==?=,第一个?同第二个?之间的gb2312代表标题内容所使用的字符集,第二个?和第三个?之间的B代表这部分内容采用的是base64编码方式,如果采用Quoted-printabel编码方式则显示Q,第三个?和第四个?之间则是“你好”经过base64编码后的字符串。

    2.2   multipart分段信息的提取

        邮件通过multipart类型将内容分隔成不同的段,各段之间的边界标识由对应multipart类型的boundary属性定义。要从邮件中提取出需要的内容,首先需要提取出邮件中的分段信息。下面的代码从一封邮件中提取出所有的multipart类型的名称和boundary属性。

    示例代码:提取multipart信息

    string emailContent = “……”;//emailContent中存储的是邮件内容

    string pat = @"\bContent-Type:\s*(?<type>\w+/\w+);\s+(type=\S(?<subtype>\S+)\S)?\s+boundary=""(?<flag>\S+)""";

    MatchCollection myMatches = Regex.Matches(emailContent,pat);

    foreach(Match nextMatch in myMatches)

    {

              GroupCollection myGroup = nextMatch.Groups;

              string type = myGroup["type"].ToString();//type变量存储multipart类型的名称

              string flag = myGroup["flag"].ToString();//flag变量存储multipart类型的boundary属性

              ……

    }

    2.3   邮件附件的提取

        邮件中的附件信息由对应的Content-Type域、 Content-Transfer-Encoding域、Content-Disposition域和multipart/mixed类型定义,前三个域定义附件的类型、名称和编码方式,multipart/mixed则定义附件同邮件其它内容的分段标识。基本格式如下:

    --boundary分段标识

    Content-Type: application/msword;

              name="readme.doc"

    Content-Transfer-Encoding: base64

    Content-Disposition: attachment;

              filename=" readme.doc "

    ……

    文件内容的Base64编码

    ……

    --boundary分段标识

        示例代码:提取邮件附件

    //boundaryMixed代表已经提取出的multipart/mixed类型的boundary标识

    //DecodeBase64为自定义的base64解码函数

    //DecodeQuotedPrintable为自定义的quoted-printable解码函数

    string emailContent = “……”;//emailContent中存储的是邮件内容

    string pat = @"\r\nContent-Type:\s*(?<filetype>\S*);\s*name=""(?<name>\ S*)""\s*Content-Transfer-Encoding:\s*(?<encoding>\S*)\s*Content- Disposition:\s*attachment;\s*filename=""(?<filename>\S+)""\s+(? <content>[\S|\r\n]+)" + "--" + boundaryMixed;

    MatchCollection myMatches = Regex.Matches(emailContent,pat,RegexOptions.Singleline);    

    foreach(Match nextMatch in myMatches)

    {

              //提取附件的类型、编码方式、文件名、内容信息

              GroupCollection myGroup = nextMatch.Groups;

              string fileType = myGroup["filetype"].ToString();

              string encoding = myGroup["encoding"].ToString();

              string fileName = myGroup["filename"].ToString();

              string content = myGroup["content"].ToString().Trim();

              byte[] attachFile;

              //根据附件的编码方式对提取出的附件内容进行解码

              if(encoding == “base64”)

              {

                        attachFile = DecodeBase64 (content);

    }

    if(encoding == “quoted-printable”)

    {

                        attachFile = DecodeQuotedPrintable (content);

    }

    //将解码后的内容写入磁盘

              FileStream fs = new FileStream("c:\\" + fileName,

    FileMode.CreateNew);

              BinaryWriter bw = new BinaryWriter(fs);

              bw.Write(attachFile);

              bw.Close();

              fs.Close();

    }

        上面的程序从邮件原文中提取出附件信息,并根据附件采用的编码类型进行解码,然后将解码后的内容按照原文件名存储到C盘根目录。同样,如果附件的文件名是中文或者其它需要编码的文字,则首先需要对文件名进行解码。

    3   总结

        本文对MIME邮件的基本格式做了分析和阐述,介绍了 MIME中几个重要的规范和定义,并给出了利用正则表达式从邮件内容中提取相关信息的基本思路和方法。在开发中需要注意的是,邮件中所含的内容决定了邮件的具体格式,multipart类型以及对应的分段标识只有在有相关内容的时候才会在邮件中出现,在开发时需要具体分析。MIME的详细技术规范可以查询 RFC的相关文档。

    展开全文
  • SMTP协议之电子邮件格式 以下是使用FOXMAIL接收邮件后,得到的邮件源码,包括正文和两个附件(.JPG, .TXT): ---------------------------------------------------------------- 以下部分为邮件服务器添加的邮件...

    SMTP协议之电子邮件格式

    以下是使用FOXMAIL接收邮件后,得到的邮件源码,包括正文和两个附件(.JPG, .TXT):


    ----------------------------------------------------------------

    以下部分为邮件服务器添加的邮件头

    ----------------------------------------------------------------

    Received:from m15-17.126.com (unknown [220.181.15.17])

             bymx10 (Coremail) with SMTP id PMCowECZWSfPlodRSu6NCw--.779S2;

             Mon,06 May 2013 19:41:03 +0800 (CST)

    DKIM-Signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; // 域名密钥识别邮件标准,判断垃圾邮件

             s=s110527;h=Received:Date:From:To:Subject:Content-Type:

             MIME-Version:Message-ID; bh=B57Zfi/+wCVQ61kM9GVkCECk1ax4OZVQDtnW // 不是base64编码

             T4lS0x8=;b=XdeYidC7bR1a1l7x3yGAMiMR5ElDx2O4/db2iPrVc0dZ7Y7ANStu     // 不是base64编码

             6d9o4l9yVysfwk8vifb0eqyxV2wp28pIlfLEGZbDDpKaLMCaLAbVXdW+2hQl4ojd    // 不是base64编码

             sJ7NiAdF1j5X2N87wktFKA8ZK4lPhBYI1yFrNIT+PODg2NzF1CX2FDM=

    Received: from zzzzyy91$126.com ( [202.205.103.22] ) by ajax-webmail-wmsvr17

     (Coremail) ; Mon, 6 May 2013 19:41:01 +0800(CST)

    X-Originating-IP: [202.205.103.22]                //初始ip地址,同一电脑不同邮箱发邮件,该值相同

    ---------------------------------------------------------------------------------------------------------

    DATA(以下内容由邮件客户端定义,为DATA命令后输入的内容)

    灰色高亮为主要内容

    --------------------------------------------------------------------------------------------------------

     

    Date: Mon, 6 May2013 19:41:01 +0800 (CST)

    From: [base64code]<zzzzyy91@126.com>

    To: [emailaddress]

    Subject: [base64 code]

    X-Priority: [integer]                                          // 邮件优先级

    X-Mailer: [Coremail Webmail Server Version SP_ntes V3.5 build      // 代理发信客户端

     20130412(21945.5326.5325) Copyright (c)2002-2013 www.mailtech.cn 126com]

    X-CM-CTRLDATA: [base64 code]                           // X-邮件服务器自定义的信息段,未知作用

    Content-Type:multipart/mixed;                               // 声明邮件内容格式

             boundary="----=_Part_354288_309861106.1367840461937"    // 声明邮件内容boundary

    MIME-Version: 1.0                                          // 声明MIME版本

    Message-ID: <>                                             // X-邮件服务器自定义的信息段

    X-CM-TRANSID:                                             //X-邮件服务器自定义的信息段

    X-CM-SenderInfo:                                           // X-邮件服务器自定义的信息段

    X-Coremail-Antispam:                                       // X-邮件服务器自定义的信息段

     

    ---------------------------------------------------------

    以下为邮件的内容

    黄色高亮部分为内容说明语句和定界符

    绿色高亮部分为邮件内容

    蓝色高亮部分为附件内容

    --------------------------------------------------------

     

    ------=_Part_354288_309861106.1367840461937                 //邮件内容开始

    Content-Type: multipart/alternative;                           //邮件内容格式

             boundary="----=_Part_354290_1105600126.1367840461937" // 邮件正文boundary

     

    ------=_Part_354290_1105600126.1367840461937              //邮件正文boundary -- 正文开始

    Content-Type: text/plain; charset=GBK                        // 邮件正文格式和字符集

    Content-Transfer-Encoding: base64

     

    [base64]mailcontent (plain)[base64]                         //邮件正文(文本格式)编码(base64

     

    ------=_Part_354290_1105600126.1367840461937              // 邮件正文boundary  --可选HTML格式

    Content-Type: text/html; charset=GBK                        //邮件正文格式和字符集

    Content-Transfer-Encoding: base64

     

    [base64]mailcontent (html)[base64]                         //邮件正文(html格式)编码(base64

     

    ------=_Part_354290_1105600126.1367840461937--           // 邮件正文boundary -- 正文结束

     

     

    ------=_Part_354288_309861106.1367840461937             // 邮件内容boundary -- 附件1开始

    Content-Type: image/jpeg; name="20130324_224528_982.jpg" // 附件格式及文件名

    Content-Transfer-Encoding: base64

    Content-Disposition: attachment;filename="20130324_224528_982.jpg"

     

    [base64](.jpg)image attachment[base64]                         //附件-图片内容编码(base64

     

    ------=_Part_354288_309861106.1367840461937                  // 邮件内容boundary -- 附件2开始

    Content-Type: text/plain; name="window data type.txt"            // 附件格式及文件名

    Content-Transfer-Encoding: base64

    Content-Disposition: attachment; filename="window datatype.txt"

     

    [base64](.txt)plain attachment[base64]                         // 附件-文本内容编码(base64

     

    ------=_Part_354288_309861106.1367840461937--                // 邮件内容boundary  -- 附件结束

    展开全文
  • 总的来说,参照rfc4021标准,mime格式分为消息头和消息体两部分(邮件头和邮件体)。 本文大致描述邮件格式,仅供参考。邮件邮件头包含了发件人、收件人、主题、时间、MIME版本、内容的类型、内容的传输编码方式...

    总的来说,参照rfc4021标准,mime格式分为消息头和消息体两部分(邮件头和邮件体)。
    本文大致描述邮件格式,仅供参考。

    邮件头

    邮件头包含了发件人、收件人、主题、时间、MIME版本、内容的类型、内容的传输编码方式等重要信息。每条信息称为一个域,由域名后加冒号(“ : ”)和信息内容构成,可以是一行,也可以占用多行。域的首行必须顶头写(即左边不能有空白字符(空格和制表符));续行则必须以空白字符打头,且第一个空白字符不是信息本身固有的,解码时要过滤掉。另外,邮件头中不允许出现空行。

    例如:
    
    Date: Wed, 15 Aug 2017 10:09:00 +0800
    From: simba@www.simba.com
    To: "simba" <simba@www.simba.com>
    Cc: "simba" <simba@www.simba.com>
    BCC: "simba" <simba@www.simba.com>
    Subject: test
    Message-ID:  <20170815100900.0E67523E1438@www.test3.com>
    X-mailer: Foxmail 6, 15, 201, 21 [cn]
    X-Spam: yes
    X-Rmilter-Greylist: Sender IP ::1 is whitelisted by configuration
    Mime-Version: 1.0
    

    包含内容解释及其他信息如下:

    邮件头

    域名                        |         含义              |       添加者  
    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                    |   段体的基位置
    

    邮件体

    邮件内容有各种各样的(既纯文本,超文本,内嵌资源(比如内嵌在超文本中的图片),附件的组合),服务器通过第一个content-type判断邮件内容,如果包含了其他内容,邮件体被分为多个段,段中可包含段,每个段又包含段头和段体两部分。

    +----------------------------------------multipart/mixed----------------------------------------+
    |                                                                                               |
    |                                                                                               |
    |   +---------------------------multipart/related---------------------------+                   |
    |   |                                                                       |                   |
    |   |                                                                       |                   |
    |   |   +---------mutipart/alternative--------------+   +-------------+     |   +-------+       |
    |   |   |                                           |   |   内嵌资源   |     |   |  附件  |      |
    |   |   |                                           |   +-------------+     |   +-------+       |
    |   |   |   +---------------+   +---------------+   |                       |                   |
    |   |   |   |   纯文本正文   |   |   超文本正文    |   |                       |                  |
    |   |   |   +---------------+   +---------------+   |   +-------------+     |   +-------+       |
    |   |   |                                           |   |   内嵌资源   |     |   |  附件  |      |
    |   |   |                                           |   +-------------+     |   +-------+       |
    |   |   +-------------------------------------------+                       |                   |
    |   |                                                                       |                   |
    |   |                                                                       |                   |
    |   +-----------------------------------------------------------------------+                   |
    |                                                                                               |
    |                                                                                               |
    +-----------------------------------------------------------------------------------------------+
    

    可以看出,如果在邮件中要添加附件,必须定义multipart/mixed段;如果存在内嵌资源,至少要定义multipart/related段;如果纯文本与超文本共存,至少要定义multipart/alternative段。什么是“至少”?举个例子说,如果只有纯文本与超文本正文,那么在邮件头中将类型扩大化,定义为multipart/related,甚至multipart/mixed,都是允许的。

    展开全文
  • MIME邮件格式的浅析

    2006-12-05 21:42:00
    在RFC 2822文档中定义了简单的 ASCII编码的Email的邮件格式,然而随着Internet的发展,Email邮件仅仅传输简单的文本已经满足不了用户的需求,为了在Email 中传输大量HTML、图像、声音以及各种附件格式,一种新的...

    在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两种类型的编码。

    (待续)


    展开全文
  • 邮件格式详解

    2019-07-07 02:01:31
    邮件本身是由ASCII字符构成,总体上分为邮件邮件体两部分,其间允许字符编码、附件、压缩等等多样化的格式。本文档参考网络官方协议标准中,请求批注的邮件相关条款,总结了邮件结构及其各部分的格式说明,给出部分...

    1        概述

    网络间传递的电子邮件需要公共认同的格式,以便于客户端邮箱软件识别拆解其间的信息。邮件本身是由ASCII字符构成,总体上分为邮件头邮件体两部分,其间允许字符编码、附件、压缩等等多样化的格式。本文档参考网络官方协议标准中,请求批注的邮件相关条款,总结了邮件结构及其各部分的格式说明,给出部分字符编码的相关解释。

    RFC( Require for comment )是Internet Official Protocol Standards标准所提供的网络协议标准系列。

            主体结构

    邮件结构包括邮件头、邮件体(可无),邮件体实际上是一行行的ASCII字符构成的简单序列,它和邮件头是靠一个空行(该行只有一个回车换行符CRLF)来区分开的。

    2.1      邮件头

    1)     长字段的断行

    邮件头由许多头字段(header fields)组成,这些字段包括字段名(field name)和字段值(field body);字段值(field body)可以分割成多行表述,叫做“可折叠”。

    断行的规则是:在一行的线性空格处,可用CRLF(回车换行)之后至少跟一个LWSP-char(空格或TAB),把原来的单行变为多行表示。

    RFC协议中推荐尽量把折叠的断行放置在特定的空格分隔处,比如,地址字段里的多个邮件地址,折叠时尽量在各地址之间,及逗号之后断行。

    2)     字段主要结构

    包括字段名(Field name),冒号(colon),字段值(Field body),结束符(CRLF);

    有些字段属于结构化字段,比如日期(Date),邮件地址(Address),有着特定的表示格式,用于系统识别。而其他字段比如”Subject” “Comments” 都被当作简单的字符串处理。

    字段表示:

    field-name ":" [ field-body ] CRLF

    字段值(Field body)可断行(见1)),内容全部都是ASCII码,元素包括句号,引用字符串,特殊token,或一般文本。字段的含义参见后文附录。

     

    3)     邮件头构造协议

           邮件头字段不是必须按照特定的顺序安排,仅仅是注意要把邮件体放在邮件头之后。邮件协议中推荐的做法是在放置邮件字段时,邮件按照以下顺序安排:”Return-Path”, “Received”, “Date”, “From”, “Subject”, “Sender”, “To”, “cc”, 等等。

    邮件协议中规定邮件由字段和邮件体正文组成,两部分之间由一个空行(该行只有包含CRLF)分隔,也就是说,在遇见的第一个空行之后所有的内容都被当作邮件体。

    Ø  转发-Forwarding

    一些系统允许接受者转发信息,保留原有的邮件头,仅添加些新的字段,这些字段以”Resent-”为前缀。及前缀”Resent-”的字段表示接受者转发的原信息。

    Ø  路径字段-Trace Field

    路径信息用来追踪信息的发送者,”via” “with” 等是记录变量。

    “Return-Path” : 该字段由信息的最后发送者添加,是关于信息原始来源的地址和回朔路径。Reply-To 字段是有信息源添加用来直接回复(地址?),而Return-Path是一个到信息原始来源的回朔路径。

    “Received” : 由每个中继服务站添加,用于帮助追踪传输中出现的错误。字段内容包括,发送、接收的主机和接收时间。参数via 用于记录信息发送后经过的物理站点,”with” 指示了使用的邮件、连接的协议。参数 id 用于标识邮件。参数for 用于记录发送者的分发的目的地址。

    Ø  信息源的字段-Originator Field

    “From/Resent-From” : 与sender 必须至少存在一个。

    “Sender/Resent-Sender”

    “Reply-To/Resent-Reply-To”   

    当自动生成回复信息的地址列表时,应当注意:如果没有”Sender”,将会使用”From” . 接收者在回复信息时,邮件sender中的信息不会被自动使用。如果”Reply-To” 字段存在,将使用该字段信息,而不是”From”字段。如果有”From” 而没有”Reply-To” ,将使用”From”。   

    Ø  接收者字段-Receiver Field

    “To/Resent-To”

    “Cc/Resent-Cc”

    “Bcc/Resent-Bcc”

    Ø  参考字段

    “Message-ID/Resent-Message-ID”

    “In-Reply-To”

    “Reference”

    “Keywords”

    4)     重要参数字段

    a)      “MIME-Version” : 所使用的网络邮件格式标准版本

    b)     “Content-type”

           邮件内容数据的类型,包括类型标识(type)和子类型标识(subtype),前者类型标识(type)声明了数据的类型,后者子类型标识(subtype)为这种数据类型指定了特定的格式。

           比如 content-type:image/xyz; 说明数据类型是图像型(image)的,图像数据格式是xyz。

           类型标识(type)与子类型标识(subtype)由斜杠”/”来分割。

           类型之后是参数集合parameter。

    邮件的数据类型分为七种,分别是: 文本(Text)、多文档(mulipart)、消息(Message)、图像(Image)、音频(audio)、视频(Video)、应用(Application)。

           文本(Text)—文字类信息,其基本的子类标识是”Plain”,即没有格式的文本。除了需要支持指定的字符集,获得文本信息不需要特殊的软件。文本子类用于多信息文本,在其上应用文字处理软件可以美化文本的外观,但文本的内容及涵义无需任何软件。因此子类型包括任何可读得文字处理格式。

           多文档(mulipart) —包含具有独立数据类型的多个部分。其中定义了4个最原始的子类型:mixed(基本类型), alternative(具有可供选择的多个格式), parallel(同时阅览的部分), digest(都是消息型的多部内容).

    消息(Message) – 未封装的消息。该类型的消息体本身部分或全部都是RFC822格式。基本子类是 ” rfc822” 。”partial”表示局部消息,允许邮件传输中可分块进行。”External-body” 表示扩展大邮件。

           图形(Image) – 需要有现实设备。子类主要是两种应用广泛的图形格式:jpeg, gif。

           声频(audio) – 基本子类 ”basic”, 需要声频输出设备。

           视频(Video) – 基本子雷 ”mpeg”, 需要视频显示设备。

           应用(Application) – 其他类型数据,无法解析的二进制数据。基本子类 ”octet-stream” ,用于不可解析的二进制数据情况,为用户提供将信息写入文件的方法。”PostScript” 表示传输脚本文档。

    Content-type类型默认为Content-type : text/plain; charset = us-ascii 。如果content-type没有明确制定,那么系统会默认为该类型。

    当遇到未知的类型时,将会把未知类型当作 ”application/octet-stream” 对待。

    c)      Content-Transfer-Encoding 头字段

    许多邮件内容是以最原始的格式传输的,8位字符或二进制数据,但对于有些协议这种格式数据就不能正确传输了。例如RFC821限制messages必须为7位US-ASCII数据,而且每行不能超过1000个字符。

    因此,有必要定义机制来把数据编码成7位短行格式。编码的目的就是用网络可以传输的方式来表达邮件内容。

           Content-Transfer-Encoding实际上就是在类型数据的本地表述和用7位邮件传输协议转化的表述之间的一种映射,比如协议RFC821(SMTP)。该字段的值就是指定编码类型的一种标识。

    其值如下:

    “7bit”,”8bit”, “quoted-printable”, “base64”, “binary”, “x-token”

           标识不区分大小写,如果没有明确指定,该字段的默认值是”7bit”。

    若值是”8bit”,”7bit”或”binary”时,表示没有做任何编码。(继续翻译)

    2.2      Content-type 字段Multipart 类型说明

    所有带前缀”Content-”的字段对正文都定义有含义,而其他得头字段一般都被邮件体部分忽略。

    协议中指出,在multipart的情况下,即多个不同的数据集合合并在同一邮件体内,此时头字段中”multipart”参数值必须存在。这时邮件体必定存在一个或多个子部分,每一个子部分都会由边界(boundary)封装,而且最后一个子部分后面必须跟一个结尾边界。每一部分都会由边界开始,然后包含着邮件子体的头信息(header),空行,然后是邮件正文。

           如果没有填写content-type 的头字段,那就是暗示相应的邮件体时US-ASCII的普通text/plain文本。

           Boundary 在作为边界值封装邮件时,其使用方法是值前加两个”-”。在一些特殊情况下,这种用法也不一定适用。

           封装部分的结尾,boundary和前面的使用格式一样的情况下,后面再加两个”-”的形式表示。

    Content-type字段参数的语法是把boundaries的值包含在引号之中。也可以没有引号,但又引号是最保险的。有一些非法字符会出现在boundary值中,如果不加引号会引起错误。

    注意封装边界必须在行的开始,后面是回车换行CRLF, 开头的CRLF会被当作边界的一部分,而不是上一块内容的一部分。边界后面跟一个CRLF和下一部分的邮件头字段,或者,两个CRLF,这种情况下不会有细一部分的邮件头。

    在边界之间(子部分头一个boundary和上一部分结尾boundary之间或者正文第一个边界之前邮件头之后),会有一些可添加额外信息的空白空间,这些空间邮件解析时会略过。

           Multipart 子类型的简要介绍:

                  Mixed: 表示个子部间互相独立,需要以特定的顺序排列。

           Alternative: 每一子部分的是相同信息的不同版本,各部分排序,最优的排在最后,但优先使用。

           Digest: 将子部分默认成message来处理。

           Parallel:同时显示多个子部

    2.3      Content-type 字段Message类型说明

    在发送邮件时,该类型会频繁使用来封装子mail邮件。通常的子类型是message/rfc822,该类型下没有必须添加的参数。额外的子类型”partial” 和 ”External-body ”,需要必要的参数。

         编码方面,该类型只允许”7bit” “8bit” 或 ”binary” 。message的头字段通常是US_ASCII的,message体内可以按照其自身的content-transfer-encoding字段值进行编码。

    1)message/rfc822

    该类型是rfc822协议的message。但不必和最外层的rfc822 message那样有from, subject,以及目的字段。该类型可以由高版本的邮件替换,及兼容MIME message。

    2)message/partial

    有些邮件发送机构限制邮件发送的大小,这样,大的邮件对象(vedio等)必须分成多部分发送。 “message/partial”说明该邮件体包含了一个大邮件的一段。该类型需要 3个参数:

    Id,尽可能保持唯一性,为了把各部组合到一起。

    Number, 该部分在整体序列中的编号。

    Total, 所分部分的总数,该参数一般在最后一部分出现。

     

    发送大邮件诸如vedio文件时,由于文件太大,超出单次发送限制,需要把文件分割成多个部分。基本过程是,把vedio类型的message,分割成多个单独的vedio类型的message, 每个部分再由”message/partial”类型的message 封装起来,并添加分段信息。

          当接收方收到该message时,各段落会`根据分割信息重新组合起来,新的信息仅是vedio类型,即去掉了外层的”message”类型封装。

    组合原则:

    (1)  拷贝第一部分的外层” message/partial” 的头信息,除了”content-”,”message-id”,”Encrypted”,”MIME-Version”,其它为必拷贝信息

    (2)  把内层的封装信息的”content-” ,”message-id”, “Encrypted”, “MIME-Version” 的头信息全部拷贝到新message中。

    (3)  第二部分和以后部分的头信息全部忽略。

                       

        

           名词解释(Word Description)

    RFC: Request For Common(Internet Official Protocol Standard)

    CRLF:Carriage-return/Line-feed

     

    转自:http://www.cppblog.com/yearner/archive/2008/11/20/67417.html

    转载于:https://www.cnblogs.com/liuzhiyun/p/9808946.html

    展开全文
  • 在RFC 2822文档中定义了简单的ASCII编码的Email的邮件格式,然而随着Internet的发展,Email邮件仅仅传输简单的文本已经满足不了用户的需求,为了在Email中传输大量HTML、图像、声音以及各种附件格式,一种新的扩展的...
  • 比如我们时常会定制业务质量报表,在邮件主体中会包含HTML、图像、声音以及附件格式等,MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)作为一种新的扩展邮件格式很好地补充了这一点,更多 ...
  • javamail邮件Multipart支持同时发text和html混合消息,alternative纯文本与超文本共存   转载:http://www.cnblogs.com/zdz8207/p/java-javamail-multipart-alternative.html   javamail邮件Multipart支持同时...
  • Pop3的邮件协议实际上是很简单的,知道那几个命令就行了,与服务器之间的交互是一问一答得方式,控制起来也容易,相对而言邮件格式的解析倒是更加麻烦一点!于是也便顺带着将MIME邮件格式给熟悉了一下!总归说来,...
  • 电子邮件普遍遵循的邮件技术规范。MIME邮件邮件头和邮件体两部分组成。邮件头包括:标题,送信人,收信人,创建日期,邮件体内容类型和邮件体编码方式等内容。邮件体包括:正文,超文本,内嵌数据和附件等内容。...
  • 邮件的结构格式-RFC822

    2018-02-24 15:27:34
    RFC822邮件内容在RFC822文档中定义,邮件内容包括两个主要的组成部分:邮件头和邮件邮件头部包括以下内容:Return-Path该字段代表邮件的回复地址Received该字段格式为Received from A by B from C(A为发送方,B为...
  • javamail邮件Multipart支持同时发text和html混合消息alternative纯文本与超文本共存 multipart/mixed:附件。 multipart/related:内嵌资源。... * 以Multipart混合格式发送邮件 * * @param ma...
  • 邮件格式说明 Mutiple Internet Mail Extensions Refer to Internet Official Protocol Standards RFC 822 1 概述 网络间传递的电子邮件需要公共认同的格式,以便于客户端邮箱软件识别拆解其间的信息。邮件本身是由...
  • smtp邮件格式(附件)

    2010-04-07 16:40:00
    已经厌倦了给你的朋友和客户发送那些单调乏味的文本通知和信件了吗?...注意对调用脚本,调用者等等的引用表示使用了将要开发的类的脚本,客户程序/MUA等等表示邮件阅读的客户程序或邮件使用代理程序。一些MIME基础MIME
1 2 3 4 5 ... 20
收藏数 6,680
精华内容 2,672