無規矩不成方圓,無標準不成網絡通信。正是在各種網絡協議和標準的基礎之上,才構建了我們現在流行的互聯網。今天給大家介紹的就是一個網絡標準格式,叫做MIME,它的全稱是Multipurpose Internet Mail Extensions,翻譯過來就是多用途Internet郵件擴展。
那么有小伙伴開始疑惑了,原來是一個郵件的擴展協議,那么它跟我們使用的Internet網絡有什么關系呢?
不急,我們慢慢道來。
MIME詳解在很久很久以前,計算機的一種流行的應用就是發郵件,最開始的時候,計算機世界的編碼方式就只有ASCII一種,但是隨著時間的推移和各種應用需求的激增,ASCII格式已經不能滿足我們的需求了,格式多類型的同時也照成了互相通信之間的困難,于是一個統一的消息格式標準產生了,這個就是MIME。
MIME可以讓郵件不僅支持ASCII,還可以支持其他的編碼方式。同時支持圖片、音頻、視頻和應用程序等多種附件。
消息體還可以支持多個part的集合,當這樣的消息郵件使用MIME格式編碼之后,就可以通過標準的郵件協議,比如SMTP、POP、IMAP等進行發送了。
因為MIME是一個標準,所以只要符合這種標準的郵件都能夠被解析成功。
很快,MIME就在郵件世界被廣泛應用,但是互聯網已經發展到使用流行的HTTP協議來訪問萬維網的時候了,MIME中定義的各種content types很自然的也成了其他協議中使用的content標準。
這種content types是在MIME頭中定義的,應用程序接收到content type之后,會根據類型中指定的消息類型,來采用對應的應用程序對消息內容進行解析。
MIME頭MIME頭很重要,是應用程序用來判斷消息格式的首要依據。MIME頭可以包含下面的字段。
MIME-Version如果存在這個消息頭,說明這個消息是遵循的是MIME格式。它的值通常是1.0。
MIME-Version: 1.0
有細心的小伙伴可以能要問了,既然有1.0,那么有沒有1.1或者2.0呢?
很抱歉,答案是沒有。因為根據MIME 共同創建者 Nathaniel Borenstein 的說法,雖然引入MIME版本號是為了在后續中對MIME進行修改和升級。但是因為MIME規范并沒有為未來MIME版本的升級進行良好的設計,所以不同的人可能對MIME版本升級后的處理方式都是不一樣的。從而導致在MIME廣泛應用的今天,很難對MIME規范進行升級。
所以,就使用1.0吧。
Content-Type如果屬性HTTP協議的同學,對這個頭應該很熟悉了吧,這個頭表示的是消息體的類型,包含了類型和子類型,比如:
Content-Type: text/plain
我們常說的MIME type就是指這個標簽。
下面是常用的MIME type:
說明 | 后綴 | 類型 |
超文本標記語言文本 | .html | text/html |
xml文檔 | .xml | text/xml |
XHTML文檔 | .xhtml | application/xhtml+xml |
普通文本 | .txt | text/plain |
RTF文本 | .rtf | application/rtf |
PDF文檔 | application/pdf | |
Microsoft Word文件 | .word | application/msword |
PNG圖像 | .png | image/png |
GIF圖形 | .gif | image/gif |
JPEG圖形 | .jpeg,.jpg | image/jpeg |
au聲音文件 | .au | audio/basic |
MIDI音樂文件 | mid,.midi | audio/midi,audio/x-midi |
RealAudio音樂文件 | .ra, .ram | audio/x-pn-realaudio |
MPEG文件 | .mpg,.mpeg | video/mpeg |
AVI文件 | .avi | video/x-msvideo |
GZIP文件 | .gz | application/x-gzip |
TAR文件 | .tar | application/x-tar |
任意的二進制數據 | application/octet-stream |
Content-Disposition是在RFC 2183中添加的一個字段,表示的是消息的展示樣式。因為之前的消息只是定義了它的消息格式,并沒有考慮消息是如何展示的問題,尤其是對于郵件來說。
比如郵件中插入了一個圖片,那么這個圖片是在我們讀消息的時候內聯展示呢?還是以附件的形式,必須要用戶下載才能看到呢?
如果是在HTTP中,響應頭字段Content-Disposition:attachment 通常用作提示客戶端將響應正文呈現為可下載文件。通常,當收到這樣的響應時,Web瀏覽器會提示用戶將其內容保存為文件,而不是將其顯示為瀏覽器窗口中的頁面。
Content-Transfer-Encoding這個字段是做什么用的呢?
我們知道,隨著數據格式越來越多,傳統的ASCII已經不能支持龐大的內容表示形式,所以出現了超出ASCII范圍的內容表示形式如Unicode。
但是對于SMTP服務器來說,能夠傳輸或者認識的編碼是有限的,如果要傳輸二進制內容,則需要使用一定的transfer encodings方式對二進制內容進行轉換。這就是Content-Transfer-Encoding的意義。
根據RFC和IANA的定義,有下面幾個transfer encodings方式:
Name | Reference |
7bit | [RFC2045] |
8bit | [RFC2045] |
binary | [RFC2045] |
quoted-printable | [RFC2045] |
base64 | [RFC2045] |
具體transfer encodings的含義,可以參考我后續的文章,這里只做簡單的介紹。
對于普通的SMTP服務器來說,可以支持7bit、quoted-printable和base64這三種編碼方式。
對于8BITMIME SMTP extension的SMTP服務器來說,還支持8bit這種編碼方式。
對于支持BINARYMIME SMTP extension的SMTP服務器來說,還支持binary這種編碼方式。
Encoded-Word根據RFC 2822,確認消息頭中的字段名和值必須使用ASCII字符。如果消息中包含非ASCII字符,則需要進行編碼。這個編碼就是encoded-word 。
編碼的格式如下:
"=?charset?encoding?encoded text?=".
charset表示的是原消息的編碼,encoding表示的是使用的編碼方式,encoded text是編碼后的消息。
Multipart messages最后,介紹一下Multipart messages,我們知道一個消息是有對應的消息類型:Content-Type的。
如果是復雜的消息,那么它里面的消息類型可能不止一種。所以這時候就需要用到Multipart messages,也就是將消息分為多個部分,每個部分都有一個Content-Type。
這種類型在郵件中比較常見。下面是一個Multipart messages的例子,在Content-Type中指定了一個消息的分割標記boundary。
MIME-Version: 1.0Content-Type: multipart/mixed; boundary=frontierThis is a message with multiple parts in MIME format.--frontierContent-Type: text/plainThis is the body of the message.--frontierContent-Type: application/octet-streamContent-Transfer-Encoding: base64PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUgYm9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==--frontier--
X 關閉
X 關閉