多用途Internet郵件擴展(多用途網際郵件擴充協議(MIME))由兩部分組成,信頭和信體。信體格式說明即(RFC 2045)接:http://www.faqs.org/rfcs/rfc2045.html。html
本備忘錄的狀態安全
本文檔講述了一種Internet團體的Internet標準跟蹤協議,它須要進一步的討論和建議以獲得改進。請參考最新版的「Internet正式協議標準」 (STD1)來得到本協議的標準化程度和狀態。本備忘錄的發佈不受任何限制。app
摘要ide
STD11,RFC 822定義了一種信息表示協議,該協議規定了US-ASCII消息報頭(message header)的詳細細節,並規定消息內容(message content)和消息體(message body)爲US-ASCII 文本格式。本系列文檔共同被稱爲MIME(Multipurpose Internet Mail Extensions),從新定義了一系列容許下列內容的信息格式:post
(1) 非US-ASCII的字符集的文本消息體(message body)this
(2) 不一樣格式的非文本消息體(message body)的擴展集編碼
(3) 多部分消息體(message body)spa
(4) 非US-ASCII字符集的文本報頭息設計
這套文檔基於更早的文檔RFC934、STD 11及RFC1049,但對它們進行了擴展和修正。因爲RFC822對消息體(message body)涉及太少,因此這套文檔與RFC822的相關性不大(不是修正RFC822 )。代理
本文檔說明了用於描述MIME消息(message)的多種報頭;第二個文檔RFC2046定義了MIME媒體類型系統的整體結構而且定義了媒體類型的初始集;第三個文檔是RFC 2047,它擴展了RFC822,容許在Internet郵件報頭中出現非US-ASCII文本;第四個文檔RFC2048說明了MIME相關程序的不一樣IANA註冊過程;第五個也是最後一個文檔RFC2049描述了MIME一致性標準,同時提供了一些關於MIME消息格式的說明性示例,還有「致謝」和「參考書目」。
這些文檔都是RFC1521、RFC1522和RFC1590的修正版,然後面三個RFC又是RFC1341和1342的修訂版。在RFC2049中的附錄描述了與之前版本的不一樣及變化。
目錄
1. 4
定義、約定和通常的BNF語法
2. 介紹
2.1 CRLF
2.2 字符集 (Character Set)
2.3 消息 (Message)
2.4 實體 (Entity)
2.5 部分主體 (Body Part)
2.6 主體 (Body)
2.7 7位的數據 (7bit Data)
2.8 8位的數據 (8bit Data)
2.9 二進制數據 (Binary Data)
2.10 行 (Lines)
3. MIME頭字段(MIME Header Fields)
4. MIME-Version頭字段
5. Content-Type 頭字段
5.1 Content-Type頭字段的語法
5.2 Content-Type的缺省值
6. Content-Transfer-Encoding頭字段
6.1 Content-Transfer-Encoding 句法
6.2 Content-Transfer-Encoding 語義
6.3 新的Content-Transfer-Encoding
6.4 解釋及使用
6.5編碼轉換
6.6 規範的編碼模式(Canonical Encoding Model)
6.7 Quoted-Printable編碼
6.8 Base64 Content-Transfer-Encoding
7. Content-ID 頭字段
8. Content-Description 頭字段
9. 另外的MIME頭字段
10. 摘要
11. 安全考慮
12. 做者地址
附錄A :收集的語法
1. 介紹
自從1982年發佈以來,RFC822已經定義了一個在Internet上傳輸文本郵件的標準格式。RFC822格式是如此的成功,它已經徹底或部分的爲你們所接受,其程度甚至超越了Internet或在RFC821中定義的Internet SMTP。也正是因爲這種格式被普遍的使用,因此許多限制因素日益約束着使用者羣體。
RFC822被制定爲用來指定文本信息格式。這樣,非文本信息――如包含音頻或圖像的多媒體信息――就徹底沒有被說起。甚至對一些文本的狀況也是這樣。RFC822不適用於那些須要多於US-ASCII字符集內容的使用者。由於RFC822沒有定義一種機制,以容許郵件包含音頻、視頻、亞洲語言的文本甚至一些歐洲的語言文本,因此須要一個額外的規範來進行說明。
RFC821/822中的一個基於郵件系統的明顯限制,就是將電子郵件消息(message)內容限制在一些由7位的US-ASCII字符組成的短行中(每行1000字節或更少[RFC821])。這就迫使使用者在用本地用戶代理(UA—User Agent,用來收發郵件的程序)發送他們的郵件以前,先要將將要發送的非文本數據轉換爲可打印的7位的US-ASCII字符。當前在Internet上使用的編碼方式有:純十六進制、uuencode、RFC1421中說明的base 64、ATK(the Andrew Toolkit Representation)及一些其它方式。
當爲在RFC822主機與X.400主機之間交換郵件信息而設計網關時,RFC822的侷限性就更加明顯了。X.400[X400]指定了一種在電子郵件消息中包含非文本內容的機制。當前,從X.400消息到RFC822消息的映射標準規定,X.400消息中的非文本部分必需要轉換爲IA5Text格式,不然,這些內容就會被丟棄,並在丟棄即將發生時,通報RFC822的使用者。當一個用戶丟掉了他想接收的內容時,這顯然是十分另人不快的。即便在用戶代理不能處理非文本內容的時候,用戶也能夠對其採起一些額外的機制,來提取有用的信息。另外,這種處理也沒有考慮到:消息最後可能會被網關轉發到支持非文本信息的X.400消息處理系統中。
這篇文檔描述了幾種機制,將它們聯合起來,能夠解決大部分的這類問題,而不會引入與RFC822不兼容的問題。詳細的說,它描述了:
(1) 「MIME-Version」頭字段。它使用一個版本號來講明消息適用於MIME,並且容許郵件處理代理將這類消息與其它由舊版本或不適用的軟件所產生的消息相區別。
(2) 在RFC1049中概括的「Content-Type」頭字段。用來指定消息數據的媒體類型(media type)及子類型,以及指定這些數據的本地表示方法(規範形式)。
(3) 「Content-Transfer-Encoding」頭字段。用來指定應用於主體(body)的編碼轉換方式及結果所處的範圍。編碼轉換不一樣於恆等轉換,它一般用於使數據經過那些有數據或字符集限制的郵件傳輸機制。
(4) 兩個附加的頭字段:「Content-ID」、「Content-Description」。它們被用來更深層的描述主體(body)中的數據。
這篇文檔中的全部的頭字段定義都服從於RFC822中規定的句法規則。特別的,除了「Content-Disposition」之外,全部的這些頭字段均可以包含RFC822註釋。這些註釋沒有實際意義,應該在MIME處理過程當中忽略。
最後,爲了說明及促進互用性,RFC2049爲以上機制的子集提供了一個基本的適用性聲明。它定義了與本文檔相適應的最低限度。
歷史註釋:在第一次閱讀時,這組文檔中所描述的幾個機制看起來會有些奇怪或具備巴洛克風格。但要注意,對於開發這組文檔的團體而言,與現有標準兼容以及遇到現有習慣時的穩健性,這二者具備相同的優先級。特別是「兼容性」永遠優先於「簡潔」。
請查閱當前版本的《因特網官方標準》(「Internet Official Protocol Standards」)以獲得本協議的標準化狀態及狀況。RFC 822和STD3,RFC1123也提供了MIME的基本背景,符合MIME的實現都不會違背它們。另外,MIME的實現者也許會關心幾個另外的RFC文檔,特別是RFC1344、RFC1345和RFC1524。
2. 定義、約定和通常的BNF語法
雖然這組文檔所定義的機制都以文字的形式給出,但仍有一部分是由RFC 822定義的BNF符號所描述。爲了瞭解這組文檔,實現者須要熟悉這些符號,並參考RFC 822,以獲得這些擴充的BNF符號的完整解釋。
本文檔中的一些擴展BNF所構成的名字參考了RFC 822中的句法規則。或要得到完整的語法則要組合以下內容:本系列每一個文檔中收集了語法的附錄、RFC822中定義的BNF以及在RFC1123中對RFC822所進行的修正。(其中給出了「return」、「data」、「mailbox」的語法變化)
在這組文檔中,全部的數值字及字節的值都由十進制的形式給出。全部的媒體類型(media type)、子類型以及參數名稱都是大小寫無關的。然而,除非特別說明,不然參數內容是大小寫相關的。
格式註釋:這部分的「註釋」提供了一些不重要的信息,在閱讀時能夠跳過它們而不會錯過任何本質的東西。添加這些註釋的基本目的是爲了說明關於這系列文檔的基礎原理,或是爲了將其恰當地放置於歷史或發展過程當中。這些信息,能夠被那些只關心創建實現的人所忽略,但對那些但願懂得爲何某種設計會被應用的人來講,這些信息仍是會有必定用處的。
2.1 CRLF
在這系列文檔中,術語CRLF指一個US-ASCII字符序列。它由兩個字符組成:CR(十進制值爲13)和LF(十進制值爲10),它們按順序放在一塊兒,構成RFC 822郵件的換行。
2.2 字符集 (Character Set)
在MIME中,術語「字符集」(character set)被用來表示一種將字節序列轉換成字符序列的方法。注意,反方向不須要絕對的、明確的轉換,由於並非全部的字符均可以被一個已知的字符集描述,並且一個字符集可能提供多於一個的字節序列,來表示某字符序列。
本定義容許將各類類型的字符編碼作爲字符集使用,如從簡單的單表映射(如US-ASCII)到多表轉換方法(如使用ISO 2022技術)等。然而與MIME字符集名稱相關的定義則必須徹底說明所要執行的映射。特別的,不容許使用外部描述信息來決定精確的映射。
註釋:術語字符集(「character set」)最初是用來描述一些簡單的方案如US-ASCII和ISO-8859-1的,它們都是從單一字節到單一字符的一對一映射。多字節編碼字符集和轉換方法使得狀況更加複雜。例如,一些團體使用術語「character encoding」,而不是MIME中所使用的術語「character set」來表示字符集,並且使用「coded character set」來抽象的表示從整數(而不是字節)到字符的映射。
2.3 消息 (Message)
術語「消息」(Message)在沒有進一步限定的時候,表示的是在Internet上傳輸的(完整或「頂層」的)RFC822消息,或者表示壓縮在「message/rfc822」或「message/partial」中的內容。
2.4 實體 (Entity)
術語「實體」(Entity)特指MIME定義的頭字段(header field)及內容(content),它們存在於消息(message)及多部分實體的一部分之中。對這些實體的規範是MIME的基本內容。由於一個實體的內容常常被稱爲「主體」(「body」),因此關於實體主體說法是有意義的。任何字段均可以出如今實體頭信息中,可是隻有那些以「content-」開頭的字段有真實的、與MIME相關的意義。注意,這並不意味着它們沒有意義,一個沒有MIME頭字段的實體(或消息)的意義由RFC822所定義。
2.5 部分主體 (Body Part)
「body part」指的是多部分實體(mulitpart entity)中的一個實體(entity)。
2.6 主體 (Body)
在沒作進一步說明的時候,術語「主體」(body)指的是一個實體(entity)的主體部分。也就是指「消息」(message)或「部分主體」(body part)的主體部分。
註釋:很明顯,以上四個概念被循環定義。由於MIME消息的整個結構就是遞歸的,因此這種狀況不可避免。
2.7 7位的數據 (7bit Data)
「7位的數據」(7bit Data)所描述的是相對較短的數據行:每行有998個或更少的8位字節內容,行分隔符爲CRLF序列[RFC-821]。其中,每個8位字節的值都不能夠大於十進制的127,也不能爲NUL(十進制的0),並且CR(十進制值爲13)和LF(十進制值爲10)字節只能夠出如今CRLF序列中。
2.8 8位的數據 (8bit Data)
「8位的數據」(8bit Data)所描述的是相對較短的數據行:每行有998個或更少的8位字節內容,行分隔符爲CRLF序列[RFC-821]。其可是字節的值能夠大於十進制的127。與「7bit data」同樣, CR(十進制值爲13)和LF(十進制值爲10)字節只能夠出如今CRLF序列中,字節的值不能爲NUL(十進制的0)。
2.9 二進制數據 (Binary Data)
「二進制數據」(Binary Data)是指能夠包含任何字節序列的數據。
2.10 行 (Lines)
「行」(Lines)被定義爲由CRLF分隔的字節序列。這與RFC 821及RFC 822一致。「行」(Lines)是指消息(Message)中的數據單位,它能夠符合或不符合用戶代理(user agent)所顯示的真實情形。
3. MIME頭字段(MIME Header Fields)
MIME定義了許多新的RFC822頭字段,用以描述MIME實體內容(entity content)。這些頭字段至少會在如下兩個地方出現:
(1) 作爲規則的RFC822消息(message)頭信息的一部分。
(2) 在多部分結構(multipart construct)裏,存在於「部分主體」(body part)頭信息中。
這些頭字段的形式定義以下:
entity-headers := [ content CRLF ]
[ encoding CRLF ]
[ id CRLF ]
[ description CRLF ]
*( MIME-extension-field CRLF )
MIME-message-headers := entity-headers
fields
version CRLF
; 當前BNF所暗含的實體頭信息
; 順序能夠被忽略。
MIME-part-headers := entity-headers
[ fields ]
; 任何不以「content-」開始的字段
; 都沒有被定義,能夠被忽略。
; 當前BNF所暗含的實體頭信息
; 順序也能夠被忽略。
不一樣的MIME頭字段的語法細節會在下面的章節中說明。
4. MIME-Version頭字段
自從1982年發佈了RFC 822以來,實際上只存在這一種Internet消息格式標準,並且幾乎沒人意識到須要聲明那些正在使用中的格式。這篇文檔是一個補充RFC822的獨立說明。雖然在這篇文檔中所作的擴展已經被定義爲與RFC 822兼容,可是,郵件處理代理仍然須要知道一個消息是不是按照新的標準構成。
爲此,本文檔定義了一個新的頭字段:「MIME-Version」。它被用來聲明Internet消息主體(message body)所使用格式的版本號。
按照本文檔格式所構成的消息(message),必須按以下格式包含這個頭字段:
MIME-Version: 1.0
這個字段就是一個聲明,它表示消息的結構符合本文檔所規定的格式。
由於從此的文檔中有可能再次擴展消息格式的標準,因此這裏給出MIME-Version頭字段的BNF:
version := "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
這樣,未來的格式說明符都被約束爲以小數點分隔的兩個整數,它們可能會替代或擴展字符:「1.0」。若是接收到一個消息,它的MIME-version值不是「1.0」,那麼就能夠假定它不符合本文檔的規範。
還有一件值得注意的事情是,不可使用MIME-Version機制來實行對媒體類型的版本控制。特別的,一些格式(如application/postscript)擁有包含在媒體格式內部的約定版本號。當這種約定存在時,MIME不會將其取代。當這種約定不存在時,MIME會在必要的時候使用「content-type」字段中的一個「version」參數進行聲明。
實現者要注意的問題:在檢查MIME-Version的時候,必定要忽略任何在RFC822中所定義的註釋部分。詳細的說,如下的MIME-Version字段是等價的:
MIME-Version: 1.0
MIME-Version: 1.0 (produced by MetaSend Vx.x)
MIME-Version: (produced by MetaSend Vx.x) 1.0
MIME-Version: 1.(produced by MetaSend Vx.x)0
當缺乏MIME-Version字段時,接收郵件的代理(不管此代理是否符合MIME要求)均可以按照本地的約定,任意的解釋消息體。在當前的使用中存在的許多這樣的約定。應該注意到,在實際中非MIME消息能夠包含任何內容。
沒法肯定一個非MIME郵件消息中只包含US-ASCII字符集的純文本內容,由於這個消息極可能使用了一些非標準的比MIME更早出現的本地約定,或是包含其它字符集的內容或非文本的內容,這樣,消息就沒法被自動的識別。(如用UUENCODE方式編碼的UNIX tar壓縮文件)
5. Content-Type 頭字段
設置「Content-Type」頭字段的目的是爲了完整的描述主體(body)中數據的內容。這樣,接收代理就能夠挑選出適當的代理或機制,來向用戶呈現數據內容,或以適當的方式處理數據。這個字段值被稱爲「媒體類型」(media type)。
歷史註釋:「Content-Type」頭字段最初是在RFC1049中定義的。RFC1049中使用的是相對簡單的,不強大的語法,可是在很大程度上與本文檔所定義的機制相兼容。
「Content-Type」頭字段經過指定媒體類型及子類型的標識符來講明實體主體(body of an entity)中數據的原始類型,並且它還會爲一些特別的媒體類型提供輔助信息。在媒體類型及子類型名稱以後,本字段中的其他部分均爲參數,它們以「屬性=值」的形式給出,至於這些參數是按什麼順序給出的,則並不重要。
總的來講,頂層的媒體類型被用來聲明數據的通常類型,而子類型則指明瞭數據的細節格式。所以,媒體類型「image/xyz」足以使用戶代理知道,接收的數據是一個圖像,哪怕這個用戶代理並不知道這種特殊的圖像類型:「xyz」。所以,這類信息能夠被用來決定是否向用戶顯示一種擁有不能識別的子類型的原始數據――此操做對於擁有不可識別子類型的文本內容來講是合理的,但不適用於圖像(image)和音頻(audio)類型的數據。因爲這個緣由,文本、圖像、音頻和視頻的子類型都不能包含有不一樣類型的嵌入信息。這種複合的格式應該由類型「multipart」和「application」所描述。
參數是媒體子類型的修飾成份,而不會影響內容的性質。一組有意義的參數依賴於媒體類型及子類型。大部分的參數只與某單一的子類型相關聯。然而,一個頂級的媒體類型能夠定義一些與其中的任何子類型都關聯的參數。對於所涉及到的內容類型(content type)或子類型(subtype)來講,參數多是必須的,也多是可選的。MIME的實現過程當中必須忽略全部不能識別的參數。
例如,「charset」參數可適用於「text」類型中的任何子類型,而「boundary」參數則是「multipart」類型中全部子類型所必須的。
不存在適用於全部媒體類型的全局參數。真正的全局機制是經過在MIME原型中定義「Content-*」頭字段而提出的。
在RFC2046中定義了最初的七個頂級媒體類型。其中的五個是不連續的類型,它們的內容是MIME處理過程所不關心的。另外的兩個類型是合成的,它們的內容須要MIME處理器進行額外的處理。
這組頂級的媒體類型(media type)已被徹底定義。但願在對這組媒體類型進行擴充的時候,只是擴充初始類型中的子類型。未來,只能夠在擴展本標準的狀況下,才能定義更多的頂級媒體類型。不管任何緣由,若是須要使用另外一個頂級類型,那麼這個類型的名稱必須以「X-」開頭,以表示它是一個非標準的狀態,以免從此與官方定義的名稱衝突。
5.1 Content-Type頭字段的語法
用一種擴充的BNF符號定義「Content-Type」頭字段,以下:
content := "Content-Type" ":" type "/" subtype
*(";" parameter)
; 匹配媒體類型或子類型時,是大小寫無關的
type := discrete-type / composite-type
discrete-type := "text" / "image" / "audio" / "video" /
"application" / extension-token
composite-type := "message" / "multipart" / extension-token
extension-token := ietf-token / x-token
ietf-token :=
standards-track RFC and registered
with IANA.>
x-token :=
no intervening white space, by any token>
subtype := extension-token / iana-token
of this form must be registered with IANA
as specified in RFC 2048.>
parameter := attribute "=" value
attribute := token
; 匹配屬性( attributes)時,
; 老是大小寫無關的
value := token / quoted-string
token := 1*
or tspecials>
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
注意,對「tspecials」的定義與RFC822中對「specials」的定義是幾乎同樣的,只是新增了三個字符:「/」、「?」、「=」,又去掉了一個字符:「.」。
還要注意到,對子類型(subtype)的定義是強制性的――子類型不能夠被Content-Type字段所忽略,所以,也就不存在缺省的子類型(subtype)。
類型、子類型、參數名稱都是大小寫無關的。例如:「TEXT」、「Text」和「TeXt」表示相同的頂級媒體類型。參數值一般都是大小寫相關的,可是一些時候也被定義爲大小寫無關的形式,這依賴於具體的應用。(例如,multipart boundary就是大小寫相關的、而「access-type」則是大小寫無關的)
注意一個用引號括起來的參數值中不包括引號,這就是說,一個被引號括起來的字符串中,引號是不包括在參數值中的,但這僅限於使用引號肯定參數值界線的狀況下。另外,格式與RFC822規則一致的註釋也容許出如今這個字段中,因些,如下兩種形式是徹底等價的:
Content-type: text/plain; charset=us-ascii (Plain text)
Content-type: text/plain; charset="us-ascii"
除了這些句法以外,對構成子類型名稱的惟一句法約束是它們在使用中不能夠相互衝突。這就是說,不能夠有兩個不一樣的團體使用「Content-Type: application/foobar」來表示兩種不一樣東西。定義一個媒體子類型的過程,並不受限制:只須要公佈這些類型的定義,並使用它們便可。所以,兩種普遍接受的定義媒體子類型的機制以下:
(1) 私有值(以「X-」開頭的名稱)能夠在兩個協同工做的代理之間雙向的定義,而不須要外部的註冊或標準化。這種值不能夠被註冊或制定爲標準。
(2) 能夠向IANA註冊新的標準,如RFC2048中描述的狀況。
這組文檔中的第二篇:RFC2046定義了媒體類型的初始集合。
5.2 Content-Type的缺省值
沒有「Content-Type」頭字段的RFC822消息被默認爲是US-ASCII字符集、純文本類型的內容。它能夠被精確的描述爲:
Content-type: text/plain; charset=us-ascii
這個缺省值是在沒有指定「Content-Type」頭字段時而使用的。並且,在遇到句法錯誤的「Content-Type」頭字段時,也會使用這個缺省值。當消息中存在「MIME-Version」頭字段,而缺乏「Content-Type」頭字段時,接收方的用戶代理也能夠假定發送者所發送的是US-ASCII字符集的純文本內容。在沒有「MIME-Version」頭字段或有錯誤語法的「Content-Type」頭字段時,仍然能夠假定其內容是US-ASCII字符集的純文本,可是這可能不是發送者的本意。