郵件格式說明
Mutiple Internet Mail Extensions
Refer to Internet Official Protocol Standards RFC 822
1 概述
網(wǎng)絡(luò)間傳遞的電子郵件需要公共認(rèn)同的格式,以便于客戶端郵箱軟件識別拆解其間的信息。郵件本身是由ASCII字符構(gòu)成,總體上分為郵件頭郵件體兩部分,其間允許字符編碼、附件、壓縮等等多樣化的格式。本文檔參考網(wǎng)絡(luò)官方協(xié)議標(biāo)準(zhǔn)中,請求批注的郵件相關(guān)條款,總結(jié)了郵件結(jié)構(gòu)及其各部分的格式說明,給出部分字符編碼的相關(guān)解釋。
RFC( Require for comment )是Internet Official Protocol Standards標(biāo)準(zhǔn)所提供的網(wǎng)絡(luò)協(xié)議標(biāo)準(zhǔn)系列。
2 主體結(jié)構(gòu)
郵件結(jié)構(gòu)包括郵件頭、郵件體(可無),郵件體實(shí)際上是一行行的ASCII字符構(gòu)成的簡單序列,它和郵件頭是靠一個空行(該行只有一個回車換行符CRLF)來區(qū)分開的。
2.1 郵件頭
1) 長字段的斷行
郵件頭由許多頭字段(header fields)組成,這些字段包括字段名(field name)和字段值(field body);字段值(field body)可以分割成多行表述,叫做“可折疊”。
斷行的規(guī)則是:在一行的線性空格處,可用CRLF(回車換行)之后至少跟一個LWSP-char(空格或TAB),把原來的單行變?yōu)槎嘈斜硎尽?/span>
RFC協(xié)議中推薦盡量把折疊的斷行放置在特定的空格分隔處,比如,地址字段里的多個郵件地址,折疊時盡量在各地址之間,及逗號之后斷行。
2) 字段主要結(jié)構(gòu)
包括字段名(Field name),冒號(colon),字段值(Field body),結(jié)束符(CRLF);
有些字段屬于結(jié)構(gòu)化字段,比如日期(Date),郵件地址(Address),有著特定的表示格式,用于系統(tǒng)識別。而其他字段比如”Subject” “Comments” 都被當(dāng)作簡單的字符串處理。
字段表示:
field-name ":" [ field-body ] CRLF
字段值(Field body)可斷行(見1)),內(nèi)容全部都是ASCII碼,元素包括句號,引用字符串,特殊token,或一般文本。字段的含義參見后文附錄。
3) 郵件頭構(gòu)造協(xié)議
郵件頭字段不是必須按照特定的順序安排,僅僅是注意要把郵件體放在郵件頭之后。郵件協(xié)議中推薦的做法是在放置郵件字段時,郵件按照以下順序安排:”Return-Path”, “Received”, “Date”, “From”, “Subject”, “Sender”, “To”, “cc”, 等等。
郵件協(xié)議中規(guī)定郵件由字段和郵件體正文組成,兩部分之間由一個空行(該行只有包含CRLF)分隔,也就是說,在遇見的第一個空行之后所有的內(nèi)容都被當(dāng)作郵件體。
Ø 轉(zhuǎn)發(fā)-Forwarding
一些系統(tǒng)允許接受者轉(zhuǎn)發(fā)信息,保留原有的郵件頭,僅添加些新的字段,這些字段以”Resent-”為前綴。及前綴”Resent-”的字段表示接受者轉(zhuǎn)發(fā)的原信息。
Ø 路徑字段-Trace Field
路徑信息用來追蹤信息的發(fā)送者,”via” “with” 等是記錄變量。
“Return-Path” : 該字段由信息的最后發(fā)送者添加,是關(guān)于信息原始來源的地址和回朔路徑。Reply-To 字段是有信息源添加用來直接回復(fù)(地址?),而Return-Path是一個到信息原始來源的回朔路徑。
“Received” : 由每個中繼服務(wù)站添加,用于幫助追蹤傳輸中出現(xiàn)的錯誤。字段內(nèi)容包括,發(fā)送、接收的主機(jī)和接收時間。參數(shù)via 用于記錄信息發(fā)送后經(jīng)過的物理站點(diǎn),”with” 指示了使用的郵件、連接的協(xié)議。參數(shù) id 用于標(biāo)識郵件。參數(shù)for 用于記錄發(fā)送者的分發(fā)的目的地址。
Ø 信息源的字段-Originator Field
“From/Resent-From” : 與sender 必須至少存在一個。
“Sender/Resent-Sender”
“Reply-To/Resent-Reply-To”
當(dāng)自動生成回復(fù)信息的地址列表時,應(yīng)當(dāng)注意:如果沒有”Sender”,將會使用”From” . 接收者在回復(fù)信息時,郵件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) 重要參數(shù)字段
a) “MIME-Version” : 所使用的網(wǎng)絡(luò)郵件格式標(biāo)準(zhǔn)版本
b) “Content-type”
郵件內(nèi)容數(shù)據(jù)的類型,包括類型標(biāo)識(type)和子類型標(biāo)識(subtype),前者類型標(biāo)識(type)聲明了數(shù)據(jù)的類型,后者子類型標(biāo)識(subtype)為這種數(shù)據(jù)類型指定了特定的格式。
比如 content-type:image/xyz; 說明數(shù)據(jù)類型是圖像型(image)的,圖像數(shù)據(jù)格式是xyz。
類型標(biāo)識(type)與子類型標(biāo)識(subtype)由斜杠”/”來分割。
類型之后是參數(shù)集合parameter。
郵件的數(shù)據(jù)類型分為七種,分別是: 文本(Text)、多文檔(mulipart)、消息(Message)、圖像(Image)、音頻(audio)、視頻(Video)、應(yīng)用(Application)。
文本(Text)—文字類信息,其基本的子類標(biāo)識是”Plain”,即沒有格式的文本。 除了需要支持指定的字符集,獲得文本信息不需要特殊的軟件。 文本子類用于多信息文本,在其上應(yīng)用文字處理軟件可以美化文本的外觀,但文本的內(nèi)容及涵義無需任何軟件。因此子類型包括任何可讀得文字處理格式。
多文檔(mulipart) —包含具有獨(dú)立數(shù)據(jù)類型的多個部分。 其中定義了4個最原始的子類型:mixed(基本類型), alternative(具有可供選擇的多個格式), parallel(同時閱覽的部分), digest(都是消息型的多部內(nèi)容).
消息(Message) – 未封裝的消息。該類型的消息體本身部分或全部都是RFC822格式。基本子類是 ” rfc822” 。”partial”表示局部消息,允許郵件傳輸中可分塊進(jìn)行。”External-body” 表示擴(kuò)展大郵件。
圖形(Image) – 需要有現(xiàn)實(shí)設(shè)備。子類主要是兩種應(yīng)用廣泛的圖形格式:jpeg, gif。
聲頻(audio) – 基本子類 ”basic”, 需要聲頻輸出設(shè)備。
視頻(Video) – 基本子雷 ”mpeg”, 需要視頻顯示設(shè)備。
應(yīng)用(Application) – 其他類型數(shù)據(jù),無法解析的二進(jìn)制數(shù)據(jù)。基本子類 ”octet-stream” ,用于不可解析的二進(jìn)制數(shù)據(jù)情況,為用戶提供將信息寫入文件的方法。”PostScript” 表示傳輸腳本文檔。
Content-type類型默認(rèn)為Content-type : text/plain; charset = us-ascii 。如果content-type沒有明確制定,那么系統(tǒng)會默認(rèn)為該類型。
當(dāng)遇到未知的類型時,將會把未知類型當(dāng)作 ”application/octet-stream” 對待。
c) Content-Transfer-Encoding 頭字段
許多郵件內(nèi)容是以最原始的格式傳輸?shù)模?/span>8位字符或二進(jìn)制數(shù)據(jù),但對于有些協(xié)議這種格式數(shù)據(jù)就不能正確傳輸了。例如RFC821限制messages必須為7位US-ASCII數(shù)據(jù),而且每行不能超過1000個字符。
因此,有必要定義機(jī)制來把數(shù)據(jù)編碼成7位短行格式。編碼的目的就是用網(wǎng)絡(luò)可以傳輸?shù)姆绞絹肀磉_(dá)郵件內(nèi)容。
Content-Transfer-Encoding實(shí)際上就是在類型數(shù)據(jù)的本地表述和用7位郵件傳輸協(xié)議轉(zhuǎn)化的表述之間的一種映射,比如協(xié)議RFC821(SMTP)。該字段的值就是指定編碼類型的一種標(biāo)識。
其值如下:
“7bit”,”8bit”, “quoted-printable”, “base64”, “binary”, “x-token”
標(biāo)識不區(qū)分大小寫,如果沒有明確指定,該字段的默認(rèn)值是”7bit”。
若值是”8bit”,”7bit”或”binary”時,表示沒有做任何編碼。(繼續(xù)翻譯)
2.2 Content-type 字段Multipart 類型說明
所有帶前綴”Content-”的字段對正文都定義有含義,而其他得頭字段一般都被郵件體部分忽略。
協(xié)議中指出,在multipart的情況下,即多個不同的數(shù)據(jù)集合合并在同一郵件體內(nèi),此時頭字段中”multipart”參數(shù)值必須存在。這時郵件體必定存在一個或多個子部分,每一個子部分都會由邊界(boundary)封裝,而且最后一個子部分后面必須跟一個結(jié)尾邊界。每一部分都會由邊界開始,然后包含著郵件子體的頭信息(header),空行,然后是郵件正文。
如果沒有填寫content-type 的頭字段,那就是暗示相應(yīng)的郵件體時US-ASCII的普通text/plain文本。
Boundary 在作為邊界值封裝郵件時,其使用方法是值前加兩個”-”。在一些特殊情況下,這種用法也不一定適用。
封裝部分的結(jié)尾,boundary和前面的使用格式一樣的情況下, 后面再加兩個”-”的形式表示。
Content-type字段參數(shù)的語法是把boundaries的值包含在引號之中。也可以沒有引號,但又引號是最保險的。有一些非法字符會出現(xiàn)在boundary值中,如果不加引號會引起錯誤。
注意封裝邊界必須在行的開始,后面是回車換行CRLF, 開頭的CRLF會被當(dāng)作邊界的一部分,而不是上一塊內(nèi)容的一部分。邊界后面跟一個CRLF和下一部分的郵件頭字段,或者,兩個CRLF,這種情況下不會有細(xì)一部分的郵件頭。
在邊界之間(子部分頭一個boundary和上一部分結(jié)尾boundary之間或者正文第一個邊界之前郵件頭之后),會有一些可添加額外信息的空白空間,這些空間郵件解析時會略過。
Multipart 子類型的簡要介紹:
Mixed: 表示個子部間互相獨(dú)立,需要以特定的順序排列。
Alternative: 每一子部分的是相同信息的不同版本,各部分排序,最優(yōu)的排在最后,但優(yōu)先使用。
Digest: 將子部分默認(rèn)成message來處理。
Parallel:同時顯示多個子部
2.3 Content-type 字段Message類型說明
在發(fā)送郵件時,該類型會頻繁使用來封裝子mail郵件。通常的子類型是message/rfc822,該類型下沒有必須添加的參數(shù)。額外的子類型”partial” 和 ”External-body ”, 需要必要的參數(shù)。
編碼方面,該類型只允許”7bit” “8bit” 或 ”binary” 。message的頭字段通常是US_ASCII的,message體內(nèi)可以按照其自身的content-transfer-encoding字段值進(jìn)行編碼。
1) message/rfc822
該類型是rfc822協(xié)議的message。但不必和最外層的rfc822 message那樣有from, subject,以及目的字段。該類型可以由高版本的郵件替換,及兼容MIME message。
2) message/partial
有些郵件發(fā)送機(jī)構(gòu)限制郵件發(fā)送的大小,這樣,大的郵件對象(vedio等)必須分成多部分發(fā)送。 “message/partial”說明該郵件體包含了一個大郵件的一段。該類型需要 3個參數(shù):
Id,盡可能保持唯一性,為了把各部組合到一起。
Number, 該部分在整體序列中的編號。
Total, 所分部分的總數(shù),該參數(shù)一般在最后一部分出現(xiàn)。
發(fā)送大郵件諸如vedio文件時,由于文件太大,超出單次發(fā)送限制,需要把文件分割成多個部分。基本過程是,把vedio類型的message,分割成多個單獨(dú)的vedio類型的message, 每個部分再由”message/partial”類型的message 封裝起來,并添加分段信息。
當(dāng)接收方收到該message時,各段落會`根據(jù)分割信息重新組合起來,新的信息僅是vedio類型,即去掉了外層的”message”類型封裝。
組合原則:
(1) 拷貝第一部分的外層” message/partial” 的頭信息,除了”content-”,”message-id”,”Encrypted”,”MIME-Version”,其它為必拷貝信息
(2) 把內(nèi)層的封裝信息的”content-” ,”message-id”, “Encrypted”, “MIME-Version” 的頭信息全部拷貝到新message中。
(3) 第二部分和以后部分的頭信息全部忽略。
名詞解釋(Word Description)
RFC: Request For Common(Internet Official Protocol Standard)
CRLF:Carriage-return/Line-feed