91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

HTTP的傳輸編碼是什么

發布時間:2021-12-01 15:49:54 來源:億速云 閱讀:130 作者:柒染 欄目:云計算

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

什么是傳輸編碼?

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

Transfer-Encoding 會改變報文的格式和傳輸的方式,使用它不但不會減少內容傳輸的大小,甚至還有可能會使傳輸變大,看似是一個不環保的做法,但是其實是為了解決一些特殊問題。

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

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

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

持久連接(Persistent Connection)

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

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

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

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

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

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

長連接帶來了另外一個問題,如何判定當前數據發送完成。

判斷傳輸完成

在早期不支持持久連接的時候,其實是可以依靠連接斷開來判定當前傳輸已經結束,大部分瀏覽器也是這么干的,但這并不是規范的操作。應該使用 Content-Length 這個頭部,來指定當前傳輸的實體內容長度。

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

Content-Length 在這里起到了一個響應實體已經發送結束的判斷依據。這樣的情況下,我們就要求 Content-Length 必須和內容實體的長度一致,如果不一致,就會出現各種問題。

如上圖所示,如果 Content-Length 小于內容實體的長度,則會截斷,反之則無法判定當前響應已經結束,會將請求持續掛起造成 Padding 狀態。

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

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

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

Transfer-Encoding:chunked

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

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

分塊傳輸的規則:

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

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

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

4. 最后通過一個數據長度值為 0 的分塊,來標記當前內容實體傳輸結束。

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

chunked 的拖掛

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

拖掛的數據,可以是服務端在末尾需要傳遞的數據,客戶端其實是可以忽略并丟棄拖掛的內容的,這就需要雙方協商好傳輸的內容了。

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

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

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

內容編碼和傳輸編碼結合

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

傳輸編碼小結

我們對傳輸編碼應該有一定的了解了。這里簡單總結一下:

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

2. 傳輸編碼主要是為了解決持久連接里將數據分塊傳輸之后,判定內容實體傳輸結束。

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

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

5. 傳輸編碼通常會配合內容編碼一起使用。

此外,傳輸編碼應該是所有 HTTP/1.1 的標準實現,應該都有支持,如果收到無法理解的經過傳輸編碼的報文,應該直接返回 501 Unimplemented 這個狀態碼來回復即可。

以上就是HTTP的傳輸編碼是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南雄市| 军事| 邹城市| 苗栗市| 双桥区| 高雄县| 海阳市| 石屏县| 新源县| 肥乡县| 略阳县| 衡阳市| 桦南县| 平罗县| 双牌县| 阿克苏市| 麟游县| 桓台县| 屏东县| 资兴市| 永登县| 宿松县| 厦门市| 宜州市| 庄浪县| 依兰县| 英德市| 万山特区| 金溪县| 连江县| 阳泉市| 鸡东县| 涟水县| 清丰县| 南城县| 临泉县| 鄂托克前旗| 台东县| 靖远县| 岳阳市| 图片|