通過HTTP傳送數(shù)據(jù)時(shí)聂宾,有些時(shí)候并不能事先確定body的長(zhǎng)度,因此無法得到Content-Length的值诊笤, 就不能在header中指定Content-Length了系谐,造成的最直接的影響就是:接收方無法通過Content-Length得到報(bào)文體的長(zhǎng)度, 那怎么判斷發(fā)送方發(fā)送完畢了呢讨跟?HTTP 1.1協(xié)議在header中引入了Transfer-Encoding纪他,當(dāng)其值為chunked時(shí), 表明采用chunked編碼方式來進(jìn)行報(bào)文體的傳輸
HTTP 1.1中有兩個(gè)實(shí)體頭(Entity-Header)直接與編碼相關(guān),分別為Content-Encoding和Transfer-Encoding.
先說Content-Encoding, 該頭表示實(shí)體已經(jīng)采用了的編碼方式.Content-Encoding是請(qǐng)求URL對(duì)應(yīng)實(shí)體(Entity)本身的一部分.比如請(qǐng)求URL為http://host/image.png.gz時(shí),可能會(huì)得到的Content-Encoding為gzip.Content-Encoding的值是不區(qū)分大小寫的,目前HTTP1.1標(biāo)準(zhǔn)中已包括的有g(shù)zip/compress/deflate/identity等.
與Content-Encoding頭對(duì)應(yīng),HTTP請(qǐng)求中包含了一個(gè)Accept-Encoding頭,該頭用來說明用戶代理(User-Agent,一般也就是瀏覽器)能接受哪些類型的編碼. 如果HTTP請(qǐng)求中不存在該頭,服務(wù)器可以認(rèn)為用戶代理能接受任何編碼類型.
接下來重點(diǎn)描述Transfer-Encoding, 該頭表示為了達(dá)到安全傳輸或者數(shù)據(jù)壓縮等目的而對(duì)實(shí)體進(jìn)行的編碼. Transfer-Encoding與Content-Encoding的不同之處在于:
1, Transfer-Encoding只是在傳輸過程中才有的,并非請(qǐng)求URL對(duì)應(yīng)實(shí)體的本身特性.
2, Transfer-Encoding是一個(gè)"跳到跳"頭,而Content-Encoding是"端到端"頭.
該頭的用途舉例如,請(qǐng)求URL為http://host/abc.txt,服務(wù)器發(fā)送數(shù)據(jù)時(shí)認(rèn)為該文件可用gzip方式壓縮以節(jié)省帶寬,接收端看到Transfer-Encoding為gzip首先進(jìn)行解碼然后才能得到請(qǐng)求實(shí)體.
此外多個(gè)編碼可能同時(shí)對(duì)同一實(shí)體使用,所以Transfer-Encoding頭中編碼順序相當(dāng)重要,它代表了解碼的順序過程.同樣,Transfer-Encoding的值也是不區(qū)分大小寫的,目前HTTP1.1標(biāo)準(zhǔn)中已包括的有g(shù)zip/compress/deflate/identity/chunked等.
Transfer-Encoding中有一類特定編碼:chunked編碼.該編碼將實(shí)體分塊傳送并逐塊標(biāo)明長(zhǎng)度,直到長(zhǎng)度為0塊表示傳輸結(jié)束, 這在實(shí)體長(zhǎng)度未知時(shí)特別有用(比如由數(shù)據(jù)庫(kù)動(dòng)態(tài)產(chǎn)生的數(shù)據(jù)). HTTP1.1標(biāo)準(zhǔn)規(guī)定,只要使用了Transfer-Encoding的地方就必須使用chunked編碼,并且chunked必須為最后一層編碼.任何HTTP 1.1應(yīng)用都必須能處理chunked編碼.
與Transfer-Encoding對(duì)應(yīng)的請(qǐng)求頭為TE,它主要表示請(qǐng)求發(fā)起者愿意接收的Transfer-Encoding類型. 如果TE為空或者不存在,則表示唯一能接受的類型為chunked.
其他與Transfer-Encoding相關(guān)的頭還包括Trailer,它與chunked編碼相關(guān),就不細(xì)述了.
顧名思義,Content-Length表示傳輸?shù)膶?shí)體長(zhǎng)度,以字節(jié)為單位(在請(qǐng)求方法為HEAD時(shí)表示會(huì)要發(fā)送的長(zhǎng)度,但并不實(shí)際發(fā)送.).Content-Length受Transfer-Encoding影響很大,只要Transfer-Encoding不為identity,則實(shí)際傳輸長(zhǎng)度由編碼中的chunked決定,Content-Length即使存在也被忽略.
關(guān)于HTTP Message Body的長(zhǎng)度
在HTTP中有消息體(Message body)和實(shí)體(Entity body)之分,簡(jiǎn)單說來在沒有Transfer-Encoding作用時(shí),消息體就是實(shí)體,而應(yīng)用了Transfer-Encoding后,消息體就是編碼后的實(shí)體,如下:
Message body = Transfer-Encoding encode(Entity body)
如何確定消息體的長(zhǎng)度? HTTP 1.1標(biāo)準(zhǔn)給出了如下方法(按照優(yōu)先級(jí)依次排列):
1, 響應(yīng)狀態(tài)(Response Status)為1xx/204/304或者請(qǐng)求方法為HEAD時(shí),消息體長(zhǎng)度為0.
2, 如果使用了非"identity"的Transfer-Encoding編碼方式,則消息體長(zhǎng)度由"chunked"編碼決定,除非該消息以連接關(guān)閉為結(jié)束.
3, 如果存在"Content-Length"實(shí)體頭,則消息長(zhǎng)度為該數(shù)值.
3, 如果消息使用關(guān)閉連接方式代表消息體結(jié)束,則長(zhǎng)度由關(guān)閉前收到的長(zhǎng)度決定. 該條對(duì)HTTP Request包含的消息體不適用.