SMTP如何處理多對象超文本數(shù)據(jù)?

起因是我們的教材[1]在對比SMTP協(xié)議和HTTP協(xié)議的時候提到的一個差異:

A third important difference concerns how a document consisting of text and images (along with possibly other media types) is handled. As we learned in Section 2.2, HTTP encapsulates each object in its own HTTP response message. Internet mail places all of the message’s objects into one message.

其中提到在處理一個既包含文本又包含圖片(有可能還有其他類型)時,HTTP會把每個對象封裝到自己的HTTP響應消息中,而因特網(wǎng)郵件(注意這里泛指所有因特網(wǎng)郵件協(xié)議而非特指SMTP)則把所有消息對象封裝在一個消息里。

現(xiàn)在的問題是SMTP究竟如何處理非文本數(shù)據(jù),是否真的如教材所言將所有類型的數(shù)據(jù)其封裝成一個消息?

SMTP的局限及其擴展MIME

原始的SMTP[2]規(guī)定了SMTP傳輸?shù)臄?shù)據(jù)需要通過7位ASCII碼進行傳輸,高位的比特數(shù)據(jù)作廢。對于英文文本來說綽綽有余,但對于其他語言的文本或者非文本數(shù)據(jù)來說就造成了很大的障礙。解決這個問題有兩種方法[3]:MIME和SMTP服務擴展(SMTP Service Extension

多用途互聯(lián)網(wǎng)郵件擴展(MIME)

MIME最早是為SMTP設計的擴展標準[4],當然后來也被擴展并用于HTTP。
在RFC1521的摘要中就已經(jīng)明確了:

In particular, this document is designed to provide facilities to include multiple objects in a single message

MIME標準是一個將多個媒體對象封裝在一個消息中的方案。具體做法就是在原來的報文頭部增加五個域:

  • MIME-VersionMIME的版本號
  • Content-Type內(nèi)容類型,通過Content-Type:<type/subtype; parameters>定義消息中傳送的內(nèi)容的類型
  • Content-Transfer-Encoding 內(nèi)容傳輸編碼,提供了除了7位ASCII碼以外的編碼方式
  • Content-Id內(nèi)容標識,可選,多消息環(huán)境中的消息唯一的標識
  • Content-Description 內(nèi)容描述,可選

通過增加這些字段可以把原來只限于文本的數(shù)據(jù)擴展成其他類型。然而遇到多個對象的時候應該如何處理?

處理多個對象

Content-Type中有一種數(shù)據(jù)類型為Multipart意為含有多個不同類型的數(shù)據(jù)部分。對于Multipart類型的數(shù)據(jù),Content-Type域除了原來的參數(shù)還會增加一個參數(shù)boundary,意為封裝這些不同類型的數(shù)據(jù)部分的邊界。兩個連字符-后加上這個邊界參數(shù)值可以分隔不同類型的數(shù)據(jù),最后再加上兩個連字符-則為最后的邊界。

借用RFC1521中的例子,這是一個包含不同編碼的文本的消息:

From: Nathaniel Borenstein <nsb@bellcore.com>
To:  Ned Freed <ned@innosoft.com>
Subject: Sample message
MIME-Version: 1.0
Content-type: multipart/mixed; boundary="simple boundary"

This is the preamble.  
It is to be ignored, though it is a handy place for mail composers to include an explanatory note to non-MIME conformant readers.
--simple boundary

This is implicitly typed plain ASCII text.
It does NOT end with a linebreak.
--simple boundary
Content-type: text/plain; charset=us-ascii

This is explicitly typed plain ASCII text.
It DOES end with a linebreak.

--simple boundary--
This is the epilogue.  It is also to be ignored.

再借用一個RFC2046[5]中的例子演示alternative子類型

From: Nathaniel Borenstein <nsb@bellcore.com>
To: Ned Freed <ned@innosoft.com> 
Date: Mon, 22 Mar 1993 09:41:09 -0800 (PST) 
Subject: Formatted text mail 
MIME-Version: 1.0 Content-Type: multipart/alternative; boundary=boundary42 

--boundary42
Content-Type: text/plain; charset=us-ascii 

... plain text version of message goes here ... 

--boundary42 
Content-Type: text/enriched 

... RFC 1896 text/enriched version of same message goes here ... 

--boundary42 
Content-Type: application/x-whatever 

... fanciest version of same message goes here ... 

--boundary42--

這里除了包含文本對象還有應用對象(x-whatever),而這個應用對象是否顯示則取決于對方使用的版本是否支持。

正如在SMTP最新的標準RFC5321[6]中所述:

SMTP transports a mail object. A mail object contains an envelope and content.

SMTP傳送的是一個郵件對象,只封裝一次。

HTTP

那么HTTP呢?既然前面提到了MIME也被借鑒到了HTTP中,處理多對象數(shù)據(jù)的時候會有什么不同么?

光說不練假把式,一言不合先抓包。

這里打開蘇州續(xù)江數(shù)碼科技有限公司的官網(wǎng)在頁面加載期間進行抓包得到

續(xù)江的進程

很顯然各個對象之間是獨立封裝的,連GET的時間都是不一樣的,第一個報文被歸為文檔類點開可以看到響應頭部

響應頭部

Content-Typetext/html,這里包含了整個網(wǎng)頁的文本信息。其他的報文則是網(wǎng)頁中的圖片。

HTTP支持Multipart么?當然啦,它是MIME標準,我們怎么能不支持它。但是這么早說支持,給人一種SMTP的感覺。這也是HTTP所支持的MIME與SMTP支持的MIME不同的地方。

HTTP支持特有的子類Multipart/Byteranges[5]而非嚴格服從MIME,原始的HTTP一開始不支持multipart,當然后續(xù)也并不推薦這種封裝策略[7],大概是出于作為拉協(xié)議本身的需求。

The "multipart/form-data" type has been specifically defined for carrying form data suitable for processing via the POST request method


  1. GB/T 7714
    Kurose J, Ross K. Computer Networking: A top-down approach[J]. 2013. ?

  2. Postel J. RFC 821: Simple Mail Tranfer Protocol[R]. IETF Network Working Group, 1982. ?

  3. Riabov V V. SMTP (Simple Mail Transfer Protocol)[J]. River College, 2005. ?

  4. Moore K. MIME (Multipurpose Internet Mail Extensions) part two: Message header extensions for non-ascii text[J]. 1993. ?

  5. RFC2046 A. Multipurpose Internet Mail Extensions (MIME), Part Two: Media Types[J]. ? ?

  6. Klensin J. RFC 5321—Simple mail transfer protocol (SMTP)[R]. RFC 5321, 2008. ?

  7. Nebel E, Masinter L. RFC 1867: Form-based File Upload in HTML[J]. Internet Engineering Task Force< URL: ftp: ds. internic. net rfc rfc1867. txt, 1995. ?

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 組織:中國互動出版網(wǎng)(http://www.china-pub.com/) RFC文檔中文翻譯計劃(http://...
    Palomar閱讀 1,648評論 0 6
  • 8. 方法定義(Method Definitions) 通用的HTTP/1.0的方法集將在下面定義,雖然該方法集可...
    Palomar閱讀 3,443評論 0 2
  • 本文包括:1、名詞解釋2、郵件收發(fā)過程3、JavaMail 知識概要4、發(fā)送一封符合 MIME 協(xié)議的 JavaM...
    廖少少閱讀 4,314評論 2 13
  • 整體Retrofit內(nèi)容如下: 1、Retrofit解析1之前哨站——理解RESTful2、Retrofit解析2...
    隔壁老李頭閱讀 15,407評論 4 39
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,318評論 25 708

友情鏈接更多精彩內(nèi)容