HTTP的傳輸編碼是什么

本篇文章給大家分享的是有關(guān)HTTP的傳輸編碼是什么,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

成都創(chuàng)新互聯(lián)公司服務(wù)項目包括漳縣網(wǎng)站建設(shè)、漳縣網(wǎng)站制作、漳縣網(wǎng)頁制作以及漳縣網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,漳縣網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到漳縣省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

什么是傳輸編碼?

傳輸編碼在 HTTP 的報文頭中,使用 Transfer-Encoding 首部進行標記,它就是指明當前使用的傳輸編碼。

Transfer-Encoding 會改變報文的格式和傳輸?shù)姆绞?,使用它不但不會減少內(nèi)容傳輸?shù)拇笮?,甚至還有可能會使傳輸變大,看似是一個不環(huán)保的做法,但是其實是為了解決一些特殊問題。

簡單來說,傳輸編碼必須配合持久連接去使用,為了在一個持久連接中,將數(shù)據(jù)分塊傳輸,并標記傳輸結(jié)束而設(shè)計的,后面會詳細講解。

在早年間的設(shè)計里,和內(nèi)容編碼使用 Accept-Encoding 來標記客戶端接收的壓縮編碼類型一樣,傳輸編碼還需要配合 TE 這個請求報文頭來使用,用于指定支持的傳輸編碼。但是在最新的 HTTP/1.1 協(xié)議規(guī)范中,只定義了一種傳輸編碼:分塊編碼(chunked),所以并不需要再依賴 TE 這個頭部。

這些細節(jié),后面都會講到。既然傳輸編碼和持久連接是息息相關(guān)的,那我們就先來了解一下什么是持久連接。

持久連接(Persistent Connection)

持久連接通俗來講,就是長連接,英文叫 Persistent Connection,其實按字面意思理解就好了。

在早期的 HTTP 協(xié)議中,傳輸數(shù)據(jù)的順序大致分為發(fā)起請求、建立連接、傳輸數(shù)據(jù)、關(guān)閉連接等步驟,而持久連接,就是去掉關(guān)閉連接這個步驟,讓客戶端和服務(wù)端可以繼續(xù)通過此次連接傳輸內(nèi)容。

這其實也是為了提高傳輸效率,我們知道 HTTP 協(xié)議是建立在 TCP 協(xié)議之上的,自然有 TCP 一樣的三次握手、慢啟動等特性,這樣每一次連接其實都是一次寶貴的資源。為了盡可能的提高 HTTP 的性能,使用持久連接就顯得很重要了。為此在 HTTP 協(xié)議中,就引入了相關(guān)的機制。

在早期的 HTTP/1.0 協(xié)議中并沒有持久連接,持久連接的概念是在后期才引入的,當時是通過 Connection:Keep-Alive 這個頭部來標記實現(xiàn),用于通知客戶端或服務(wù)端相對的另一端,在發(fā)送完數(shù)據(jù)之后,不要斷開 TCP 連接,之后還需要再次使用。

而在 HTTP/1.1 協(xié)議中,發(fā)現(xiàn)持久連接的重要性了,它規(guī)定所有的連接必須都是持久的,除非顯式的在報文頭里,通過 Connection:close 這個首部,指定在傳輸結(jié)束之后會關(guān)閉此連接。

實際上在 HTTP/1.1 中Connect 這個頭部已經(jīng)沒有 Keep-Alive 這個取值了,由于歷史原因,很多客戶端和服務(wù)端,依然保留了這個報文頭。

長連接帶來了另外一個問題,如何判定當前數(shù)據(jù)發(fā)送完成。

判斷傳輸完成

在早期不支持持久連接的時候,其實是可以依靠連接斷開來判定當前傳輸已經(jīng)結(jié)束,大部分瀏覽器也是這么干的,但這并不是規(guī)范的操作。應(yīng)該使用 Content-Length 這個頭部,來指定當前傳輸?shù)膶嶓w內(nèi)容長度。

下面舉個例子,在保持持久連接的情況下,依賴 Content-Length 來確定數(shù)據(jù)發(fā)送完畢。

Content-Length 在這里起到了一個響應(yīng)實體已經(jīng)發(fā)送結(jié)束的判斷依據(jù)。這樣的情況下,我們就要求 Content-Length 必須和內(nèi)容實體的長度一致,如果不一致,就會出現(xiàn)各種問題。

如上圖所示,如果 Content-Length 小于內(nèi)容實體的長度,則會截斷,反之則無法判定當前響應(yīng)已經(jīng)結(jié)束,會將請求持續(xù)掛起造成 Padding 狀態(tài)。

理想情況下,我們在響應(yīng)一個請求的時候,就需要知道它的內(nèi)容實體的大小。但是在實際應(yīng)用中,有些時候內(nèi)容實體的長度并沒有那么容易獲得。例如內(nèi)容實體來自網(wǎng)絡(luò)文件、或者是動態(tài)生成的。這個時候如果依然想要提前獲取到內(nèi)容實體的長度,只能開一個足夠大的 Buffer,等內(nèi)容全部緩存好了再計算。

但這并不是一個好的方案,全部緩存到 Buffer 里,第一會消耗更多的內(nèi)存,第二也會更耗時,讓客戶端等待過久。

此時就需要一個新的機制,不依賴 Content-Length 的值,來判定當前內(nèi)容實體是否傳輸完成,此時就需要 Transfer-Encoding 這個頭部來判定。

Transfer-Encoding:chunked

前面也提到,Transfer-Encoding 在最新的 HTTP/1.1 協(xié)議里,就只有 chunked 這個參數(shù),標識當前為分塊編碼傳輸。

分塊編碼傳輸既然只有一個可選的參數(shù),我們就只需要指定它為 Transfer-Encoding:chunked ,后續(xù)我們就可以將內(nèi)容實體包裝一個個塊進行傳輸。

分塊傳輸?shù)囊?guī)則:

1. 每個分塊包含一個 16 進制的數(shù)據(jù)長度值和真實數(shù)據(jù)。

2. 數(shù)據(jù)長度值獨占一行,和真實數(shù)據(jù)通過 CRLF(\r\n) 分割。

3. 數(shù)據(jù)長度值,不計算真實數(shù)據(jù)末尾的 CRLF,只計算當前傳輸塊的數(shù)據(jù)長度。

4. 最后通過一個數(shù)據(jù)長度值為 0 的分塊,來標記當前內(nèi)容實體傳輸結(jié)束。

在這個例子中,首先在響應(yīng)頭部里標記了 Transfer-Encoding: chunked,后續(xù)先傳遞了第一個分塊 “0123456780”,長度為 b(11 的十六進制),之后分別傳輸了 “Hello CxmyDev” 和 “123”,最后以一個長度為 0 的分塊標記當前響應(yīng)結(jié)束。

chunked 的拖掛

當我們使用 chunked 進行分塊編碼傳輸?shù)臅r候,傳輸結(jié)束之后,還有機會在分塊報文的末尾,再追加一段數(shù)據(jù),此數(shù)據(jù)稱為拖掛(Trailer)。

拖掛的數(shù)據(jù),可以是服務(wù)端在末尾需要傳遞的數(shù)據(jù),客戶端其實是可以忽略并丟棄拖掛的內(nèi)容的,這就需要雙方協(xié)商好傳輸?shù)膬?nèi)容了。

在拖掛中可以包含附帶的首部字段,除了 Transfer-Encoding、Trailer 以及 Content-Length 首部之外,其他 HTTP 首部都可以作為拖掛發(fā)送。

一般我們會使用拖掛來傳遞一些在響應(yīng)報文開始的時候,無法確定的某些值,例如:Content-MD5 首部就是一個常見的在拖掛中追加發(fā)送的首部。和長度一樣,對于需要分塊編碼傳輸?shù)膬?nèi)容實體,在開始響應(yīng)的時候,我們也很難算出它的 MD5 值。

注意這里在頭部增加了 Trailder,用以指定末尾還會傳遞一個 Content-MD5 的拖掛首部,如果有多個拖掛的數(shù)據(jù),可以使用逗號進行分割。

內(nèi)容編碼和傳輸編碼結(jié)合

內(nèi)容編碼和傳輸編碼一般都是配合使用的。我們會先使用內(nèi)容編碼,將內(nèi)容實體進行壓縮,然后再通過傳輸編碼分塊發(fā)送出去。客戶端接收到分塊的數(shù)據(jù),再將數(shù)據(jù)進行重新整合,還原成最初的數(shù)據(jù)。

傳輸編碼小結(jié)

我們對傳輸編碼應(yīng)該有一定的了解了。這里簡單總結(jié)一下:

1. 傳輸編碼使用 Transfer-Encoding 首部進行標記,在最新的 HTTP/1.1 協(xié)議里,它只有 chunked 這一個取值,表示分塊編碼。

2. 傳輸編碼主要是為了解決持久連接里將數(shù)據(jù)分塊傳輸之后,判定內(nèi)容實體傳輸結(jié)束。

3. 分塊的格式:數(shù)據(jù)長度(16進制)+ 分塊數(shù)據(jù)。

4. 如果還有額外的數(shù)據(jù),可以在結(jié)束之后,使用 Trailer 進行拖掛傳輸額外的數(shù)據(jù)。

5. 傳輸編碼通常會配合內(nèi)容編碼一起使用。

此外,傳輸編碼應(yīng)該是所有 HTTP/1.1 的標準實現(xiàn),應(yīng)該都有支持,如果收到無法理解的經(jīng)過傳輸編碼的報文,應(yīng)該直接返回 501 Unimplemented 這個狀態(tài)碼來回復(fù)即可。

以上就是HTTP的傳輸編碼是什么,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

當前名稱:HTTP的傳輸編碼是什么
文章源于:http://bm7419.com/article44/jddghe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、外貿(mào)建站、微信小程序服務(wù)器托管、云服務(wù)器、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計