HTTP要確保它承載的「貨物」知足如下條件:html
1、報文是箱子,實體是貨物算法
若是把HTTP報文想象成因特網貨運系統中的箱子,那麼HTTP實體就是報文中實際的貨物。瀏覽器
HTTP實體首部描述了HTTP報文的內容。HTTP/1.1版定義瞭如下10個基本字體首部字段。緩存
1 實體主體安全
首部字段以一個空白的CRLF行結束,隨後就是實體主體的原始內容。服務器
2、Content-Length:實體的大小網絡
Content-Length首部指示出報文中實體主體的字節大小。這個大小是包含了全部內容編碼的,好比,對文本文件進行了gzip壓縮的話,Content-Length首部就是壓縮後的大小,而不是原始大小。架構
除非使用了分塊編碼,不然Content-Length首部就是帶有實體主體的報文必須使用的。使用Content-Length首部是爲了可以檢測出服務器崩潰而致使的報文截尾,並對共享持久鏈接的多個報文進行正確分段。併發
1 檢測截尾post
HTTP的早期版本採用關閉鏈接的辦法來劃定報文的結束。可是,沒有Content-Length的話,客戶端沒法區分究竟是報文結束時正常的鏈接關閉,仍是報文傳輸中因爲服務器崩潰而致使的鏈接關閉。客戶端須要經過Content-Length來檢測報文截尾。
報文截尾的問題對緩存代理服務器來講尤爲嚴重。若是緩存服務器收到被截尾的報文卻沒有識別出截尾的話,它可能會存儲不完整的內容並屢次使用它來提供服務。緩存代理服務器一般不會爲沒有顯示Content-Length首部的HTTP主體作緩存,以此減小緩存已截尾報文的風險。
2 Content-Length與持久鏈接
Content-Length首部對於持久鏈接是必不可少的。若是響應經過持久鏈接傳送,就可能有另外一條HTTP響應緊隨其後。客戶端經過Content-Length首部就能夠知道報文在何處結束,下一條報文從何處開始。
3 內容編碼
Content-Length首部說明的是編碼後(encoded)的主體的字節長度,而不是未編碼的原始主體的長度。
4 肯定實體主體長度的規則
3、實體摘要
服務器使用Content-MD5首部發送對實體主體運行MD5算法的結果。只有產生響應的原始服務器能夠計算併發送Content-MD5首部。中間代理和緩存不該當修改或添加這個首部,不然就會與驗證端到端完整性的這個最終目的相沖突。Content-MD5首部是在對內容作了全部須要的內容編碼以後,尚未作任何傳輸編碼以前,計算出來的。爲了驗證報文的完整性,客戶端必須先進行傳輸編碼的解碼,而後計算所獲得的未進行傳輸編碼的實體主體的MD5。
4、媒體類型和字符集
Content-Type首部字段說明了實體主體的MIME類型。MIME類型是標準化的名字,用以說明做爲貨物運載實體的基本媒體類型。客戶端應用程序使用MIME類型來解釋和處理其內容。
1 文本的字符編碼
Content-Type: text/html; charset=iso-8859-4
2 多部分媒體類型
MIME中的multipart(多部分)電子郵件報文中包含多個報文,它們合在一塊兒做爲單一的複雜報文發送。每一部分都是獨立的,有各自的描述其內容的集;不一樣的部分之間用分界字符串鏈接在一塊兒。
3 多部分表格提交
HTTP使用Content-Type:multipart/form-data或Content-Type:multipart/mixed這樣的首部以及多部分主體來發送這種請求,舉例以下:
Content-Type: multipart/form-data; boundary=[abcdefghijklmnopqrstuvwxyz]
其中的boundary參數說明了分割主體中不一樣部分所用的字符串。
<FORM action="http://server.com/cgi/handle" enctype="multipart/form-data" method="post"> <P> What is your name?<INPUT type="text" name="submit-name"><BR> What files are you sending?<INPUT type="file" name="files"><BR> <INPUT type="submit" value="Send"><INPUT type="reset"> </FORM>
用戶代理可能會發回下面這樣的數據:
Content-Type: multipart/form-data; boundary=AaB03x --AzBo3x Content-Dispositon: form-data; name="submit-name" Sally --AaB03x Content-Disposition: form-data; name="files" Content-Type: multipart/mixed; boundary=BbC04y --BbC04y Content-Disposition: file; filename="essayfile.txt" Content-Type: text/plain --BbC04y Content-Disposition: file; filename="imagefile.gif" Content-Type: image/gif ...contents of imagefile.gif... --BbC04y --AaB03x--
4 多部分範圍響應
HTTP對範圍請求的響應也能夠是多部分的。這樣的響應中有Content-Type: mltipart/byterange首部和帶有不一樣範圍的多部分主體。
5、內容編碼
HTTP應用程序有時在發送以前須要對內容進行編碼。
1 內容編碼過程
2 內容編碼類型
HTTP定義了一些標準的內容編碼類型,並容許用擴展編碼的形式增添更多的編碼。Content-Encoding首部就用這些標準化的代號來講明編碼時使用的算法。
3 Accept-Encoding首部
爲了不服務器使用客戶端不支持的編碼方式,客戶端就把本身支持的內容編碼方式列表放在請求的Accept-Encoding首部裏發出去。若是HTTP請求中沒有包含Accept-Encoding首部,服務器端就能夠假設客戶端可以接收任何編碼方式。
6、傳輸編碼和分塊編碼
傳輸編碼也是做用在實體主體上的可逆變換,但使用它們時因爲架構方面的緣由,同內容的格式無關。使用傳輸編碼是爲了改變報文中的數據在網絡上傳輸的方式。
1 可靠傳輸
在HTTP中,只有少數一些狀況下,所傳輸的報文主體可能會引起問題。其中兩種狀況以下所述。
1)未知的尺寸
若是不先生成內容,某些網關應用程序和內容編碼器就沒法肯定報文主體的最終大小。一般,這些服務器但願在知道大小以前就開始傳輸數據。由於HTTP協議要求Content-Length首部必須在數據以前,有些服務器就是用傳輸編碼來發送數據,並用特別的結束腳註代表數據結束。
2)安全性
你能夠用傳輸編碼來把報文內容擾亂,而後再共享的傳輸網絡上發送。不過,因爲像SSL這樣的傳輸層安全體系的流行,就不多須要靠傳輸編碼來實現安全性了。
2 Transfer-Encoding首部
HTTP協議中只定義了下面兩個首部來描述和控制傳輸編碼。
下面的例子中,請求使用了TE首部來告訴服務器它能夠接收分塊編碼(若是是HTTP/1.1應用程序的話,這就是必須的)而且願意接受附在分塊編碼的報文結尾上的拖掛:
GET /new_products.html HTTP/1.1 Host: www.joes-hardware.com User-Agent: Mozilla/4.61 [en] (WinNT; I) TE: trailers, chunked ...
對它的相應中包含Trasfer-Encoding首部,用於告訴接收方已經用分塊編碼對報文進行了傳輸編碼:
HTTP/1.1 200 OK Transfer-Encoding: chunked Server: Apache/3.0 ...
在這個起始首部以後,報文的結構就將發生改變。
傳輸編碼的值都是大小寫無關的。HTTP/1.1規定在TE首部和Transfer-Encoding首部中使用傳輸編碼值。最新的HTTP規範只定義了一種傳輸編碼,就是分塊編碼。
3 分塊編碼
分塊編碼把報文分割爲若干個大小已知的塊。塊之間是緊挨着發送的,這樣就不須要在發送以前知道整個報文的大小。
7、驗證碼和新鮮度
1 新鮮度
服務器能夠用這兩個首部之一來提供這種信息:Expires(過時)和Cache-Control(緩存控制)。
Expires首部規定文檔「過時」的具體時間——此後就不該當認爲它仍是最新的。Expires首部的語法以下:
Expires: Sun Mar 18 23:59:59 GMT 2001
客戶端和服務器爲了能正確使用Expires首部,它們的始終必須同步。
Cache-Control首部能夠用秒數來規定文檔最長使用期——從文檔離開服務器以後算起的總計時間。使用期不與時鐘同步,所以能夠給出更精確的結果。
2 有條件的請求與驗證碼
當請求緩存服務器中的副本時,若是它再也不新鮮,緩存服務器就須要保證它有一個新鮮的副本。緩存服務器能夠向原始服務器獲取當前的副本。但在不少狀況下,原始服務器上的文檔仍然與緩存中已過時的副本相同。若是服務器上的文檔和已過時的緩存副本相同,而緩存服務器仍是要從原始服務器上取文檔的話,那緩存服務器就是在浪費網絡帶寬,給緩存服務器和原始服務器增長沒必要要的負載,是全部的事情都變慢了。
爲了不這種狀況,HTTP爲客戶端提供了一種方法,僅當資源改變時才請求副本,這種特殊請求稱爲有條件的請求。有條件的請求是標準的HTTP請求報文,但僅當某個特定條件爲真時才執行。
GET /announce.html HTTP/1.0 If-Modified-Since: Sat, 29 Jun 2002, 14:30:00 GMT
有條件的請求是經過以「If-」開頭的有條件的首部來實現的。
歸納一下,當客戶端屢次訪問同一個資源時,首先須要判斷它當前的副本是否是仍然新鮮。若是再也不新鮮,它們就必須從服務器獲取最新的版本。爲了不在資源沒有改變的狀況下收到一份相同的副本,客戶端能夠向服務器發送有條件的請求,說明能惟一標識客戶端當前副本的驗證碼。只在資源和客戶端的副本不一樣的狀況下服務器纔會發送其副本。