HTTP 報(bào)文內(nèi)的 HTTP 信息
1. HTTP 報(bào)文
用于 HTTP 協(xié)議交互的信息被稱為 HTTP 報(bào)文。
請求端(客戶端)的 HTTP 報(bào)文叫請求報(bào)文
響應(yīng)端 (服務(wù)器端)的 HTTP 報(bào)文叫響應(yīng)報(bào)文
HTTP 報(bào)文本身是由多行數(shù)據(jù)構(gòu)成的字符串文本
HTTP 報(bào)文大致可分為報(bào)文首部和報(bào)文主體兩塊。

2. 請求報(bào)文及響應(yīng)報(bào)文的結(jié)構(gòu)
-
請求報(bào)文結(jié)構(gòu)
請求報(bào)文結(jié)果.png -
響應(yīng)報(bào)文結(jié)構(gòu)
響應(yīng)報(bào)文結(jié)構(gòu).png -
請求報(bào)文實(shí)例
請求報(bào)文實(shí)例.png -
響應(yīng)報(bào)文實(shí)例
響應(yīng)報(bào)文實(shí)例.png
請求報(bào)文和響應(yīng)報(bào)文的首部內(nèi)容由以下數(shù)據(jù)組成
-
請求行
包含用于請求的方法,請求 URI 和 HTTP 版本。
-
狀態(tài)行
包含表明響應(yīng)結(jié)果的狀態(tài)碼,原因短語和 HTTP 版本。
-
首部字段
包含表示請求和響應(yīng)的各種條件和屬性的各類首部,一般有四種首部。
通用首部
請求首部
響應(yīng)首部
實(shí)體首部
-
其他
可能包含 HTTP 的 RFC 里未定義的首部(Cookie 等)
3. 編碼提升速率
HTTP 在傳輸數(shù)據(jù)時可以按照數(shù)據(jù)原貌直接傳輸,也可以在傳輸過程中通過編碼提升傳輸速率。
通過在傳輸時編碼,能有效處理大量的訪問請求。
編碼的操作需要計(jì)算機(jī)來完成,因此會消耗更多的 CPU 資源。
3.1 報(bào)文實(shí)體和實(shí)體主體的差異
-
報(bào)文(message)
是 HTTP 通信中的基本單位,由 8位組 字節(jié)流組成,通過 HTTP 通信傳輸。
-
實(shí)體(entity)
作為請求和響應(yīng)的有效載荷數(shù)據(jù)被傳輸,其內(nèi)容由實(shí)體首部和實(shí)體主體組成。
HTTP 報(bào)文的主體用于傳輸請求或響應(yīng)的實(shí)體主體
通常報(bào)文主體等于實(shí)體主體,只有當(dāng)傳輸中進(jìn)行編碼時,實(shí)體主體的內(nèi)容發(fā)生變化,才導(dǎo)致它和報(bào)文主體的差異。
3.2 壓縮傳輸?shù)膬?nèi)容編碼
內(nèi)容編碼指明應(yīng)用在實(shí)體內(nèi)容上的編碼格式,并保持實(shí)體原樣壓縮。內(nèi)容編碼后的實(shí)體由客戶端接受并負(fù)責(zé)解碼。

常見的內(nèi)容編碼由以下幾種:
gzip(GNU zip)
compress(UNIX 系統(tǒng)的標(biāo)準(zhǔn)壓縮)
deflate(zlib)
identity(不進(jìn)行編碼)
3.3 分割發(fā)送的分塊傳輸碼
把實(shí)體主體分塊的功能稱為分塊傳輸碼(Chunked Transfer Coding)。

分塊傳輸碼會將實(shí)體主體分成多個部分(塊),每一塊都會用十六進(jìn)制來標(biāo)識塊的大小,而實(shí)體主體的最后一塊會使用 0(CR+LF) 來標(biāo)記。
使用分塊傳輸碼的實(shí)體主體會由接受的客戶端負(fù)責(zé)解碼,恢復(fù)到編碼前的實(shí)體主體。
HTTP/1.1 中存在一種稱為傳輸碼(Transfer Coding)的機(jī)制,它可以在通信時按照某種編碼方式傳輸,但只定義作用于分塊傳輸編碼中。
4. 發(fā)送多種數(shù)據(jù)的多部分對象集合
HTTP 協(xié)議中采用 多部分對象集合,可以使發(fā)送的一份報(bào)文主體含有多類型實(shí)體,通常在圖片或文本文件上傳時使用。
多部分對象集合包含的對象如下:
-
multipart/form-data
在 Web 表單文件上傳時使用。
Content-Type: multipart/form-data; boundary=AaB03x --AaB03x Content-Disposition: form-data; name="field1" Joe Blow --AaB03x Content-Disposition: form-data; name="pics"; filename="file1.txt" Content-Type: text/plain ...(file1.txt的數(shù)據(jù))... --AaB03x-- -
multipart/byteranges
狀態(tài)碼 206(Partial Content 部分內(nèi)容)響應(yīng)報(bào)文包含了多個范圍的內(nèi)容時使用。
HTTP/1.1 206 Partial Content Date: Fri, 13 Jul 2012 02:45:26 GMT Last-Modified: Fri, 31 Aug 2007 02:02:20 GMT Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES --THIS_STRING_SEPARATES Content-Type: application/pdf Content-Range: bytes 500-999/8000 ...(范圍指定的數(shù)據(jù))... --THIS_STRING_SEPARATES Content-Type: application/pdf Content-Range: bytes 7000-7999/8000 ...(范圍指定的數(shù)據(jù))... --THIS_STRING_SEPARATES--
在 HTTP 報(bào)文中使用多部分對象集合時,需要在首部字段加上 Content-type。
使用 boundary 字符串來劃分多部分對象集合指明的各類實(shí)體。
在 boundary 字符串指定的各個實(shí)體的起始行之前插入 " -- " 標(biāo)記,如(-
-AaB03x、--THIS_STRING_SEPARATES)。
在多部分對象集合對應(yīng)的字符串的最后插入"--"(如:--AaB03x--、--THIS_STRING_SEPARATES--) 作為結(jié)束。
多部分對象集合的每個部分類型中,都可以含有首部字段,還可以在某個部分中嵌套使用多部分對象集合。
5. 獲取部分內(nèi)容的范圍請求
指定范圍發(fā)送的請求叫做范圍請求(Range Request)。
對一份 10000 字節(jié)大小的資源,使用范圍請求,可以只請求 5001~10000 字節(jié)內(nèi)的資源。

指定范圍請求,會用到首部字段 Range 指定資源的 byte 范圍。
byte 范圍的指定形式如下:
-
5001~10000 字節(jié)
Range: bytes=5001-10000 -
從 5001 字節(jié)之后全部的
Range: bytes=5001- -
從一開始到 3000 字節(jié)和 5000~7000 字節(jié)的多重范圍
Range: bytes=-3000, 5000-7000
針對范圍請求,響應(yīng)會返回狀態(tài)碼為 206 Partial Content 的響應(yīng)報(bào)文。
多重范圍的范圍請求,響應(yīng)會在首部字段 Content-type 標(biāo)明 mulitpart/byteranges 后返回響應(yīng)報(bào)文。
如果服務(wù)器端無法響應(yīng)范圍請求,則會返回狀態(tài)碼 200 OK 和完整的實(shí)體內(nèi)容。
6. 內(nèi)容協(xié)商返回最合適的內(nèi)容
當(dāng)瀏覽器默認(rèn)語言為中文或英語,訪問相同 URI 的 Web 頁面時,則會顯示對應(yīng)語言的 Web 頁面。這樣的機(jī)制稱為內(nèi)容協(xié)商(Content Negotiation)。

內(nèi)容協(xié)商是指客戶端和服務(wù)器端就響應(yīng)的資源內(nèi)容進(jìn)行交涉,然后提供給客戶端最合適的資源。內(nèi)容協(xié)商會以響應(yīng)資源的語言、字符集、編碼方式等作為判斷的基準(zhǔn)。
包含在請求報(bào)文中的某些首部字段就是判斷的基準(zhǔn),如:
Accept
Accept-Charset
Accept-Encoding
Accept-Language
Content-Language
內(nèi)容協(xié)商類型如下:
-
服務(wù)器驅(qū)動協(xié)商(Server-driven Negotiation)
由服務(wù)器端進(jìn)行內(nèi)協(xié)商,以請求的首部字段作為參考,在服務(wù)器端自動處理。
-
客戶端驅(qū)動協(xié)商(Agent-driven Negotiation)
由客戶端進(jìn)行內(nèi)容協(xié)商,用戶從瀏覽器顯示的可選項(xiàng)列表中手動選擇,還可以利用 JavaScript 腳本在 Web 頁面自動進(jìn)行上述選擇。
-
透明協(xié)商(Transparent Negotiation)
服務(wù)器驅(qū)動和客戶端驅(qū)動的結(jié)合體,由服務(wù)器和客戶端各自進(jìn)行內(nèi)容協(xié)商的一種方法。



