帶你看透HTTP協議
HTTP請求階段
HTTP請求的構建
建立連接以後,瀏覽器就要發送請求了
請求的格式如下:
HTTP報文分為3部分
1. 請求行
請求行包括URL,HTTP版本,以及請求方法等
2. 首部的欄位
首部是 key value,通過冒號分隔
例如,Accept-Charset,表示客戶端可以接受的字元...
例如,Accept-Charset,表示客戶端可以接受的字符集。防止傳過來的是另外的字符集,從而導致出現亂碼。
再如,Content-Type是指正文的格式。例如,我們進行POST 的請求,如果正文是 JSON,那麼我們就應該將這個值設置為 JSON。
3.實體
實體部分就是請求的一些參數
HTTP請求的發送
HTTP 協議是基於 TCP 協議的,所以它使用面向連接的方式發送請求,通過 stream 二進位流的方式傳給對方。當然,到了 TCP 層,它會把二進位流變成一個的報文段發送給伺服器。
TCP 層發送每一個報文的時候,都需要加上自己的地址(即源地址)和它想要去的地方(即目標地址),將這兩個信息放到 IP 頭裡面,交給 IP 層進行傳輸。
IP 層需要查看目標地址和自己是否是在同一個區域網。如果是,就發送 ARP 協議來請求這個目標地址對應的 MAC 地址,然後將源 MAC 和目標 MAC 放入 MAC 頭,發送出去即可;如果不在同一個區域網,就需要發送到網關,還要需要發送 ARP 協議,來獲取網關的 MAC 地址,然後將源 MAC 和網關 MAC 放入 MAC 頭,發送出去。
網關收到包發現 MAC 符合,取出目標 IP 地址,根據路由協議找到下一跳的路由器,獲取下一跳路由器的 MAC 地址,將包發給下一跳路由器。
這樣路由器一跳一跳終於到達目標的區域網。這個時候,最後一跳的路由器能夠發現,目標地址就在自己的某一個出口的區域網上。於是,在這個區域網上發送 ARP,獲得這個目標地址的 MAC 地址,將包發出去。
目標的機器發現 MAC 地址符合,就將包收起來;發現 IP 地址符合,根據 IP 頭中協議項,知道自己上一層是 TCP 協議,於是解析 TCP 的頭,裡面有序列號,需要看一看這個序列包是不是我要的,如果是就放入緩存中然後返回一個 ACK,如果不是就丟棄。
TCP 頭裡面還有埠號,HTTP 的伺服器正在監聽這個埠號。於是,目標機器自然知道是 HTTP 伺服器這個進程想要這個包,於是將包發給 HTTP 伺服器。HTTP 伺服器的進程看到,原來這個請求是要訪問一個網頁,於是就把這個網頁發給客戶端。
HTTP響應的構建
響應的結構跟請求的結構差不多
其中狀態碼會反應 HTTP 請求的結果。「200」意味著大吉大利;而我們最不想見的,就是「404」,也就是「服務端無法響應這個請求」。
在返回的頭部裡面也會有Content-Type,表示返回的是 HTML,還是 JSON。
這些段加上 TCP 頭後會交給 IP 層,然後把剛才的發送過程反向走一遍。雖然兩次不一定走相同的路徑,但是邏輯過程是一樣的,一直到達客戶端。
客戶端發現 MAC 地址符合、IP 地址符合,於是就會交給 TCP 層。根據序列號看是不是自己要的報文段,如果是,則會根據 TCP 頭中的埠號,發給相應的進程。這個進程就是瀏覽器,瀏覽器作為客戶端也在監聽某個埠。
當瀏覽器拿到了 HTTP 的報文。發現返回「200」,一切正常,於是就從正文中將 HTML 拿出來。HTML 是一個標準的網頁格式。瀏覽器只要根據這個格式,展示出一個絢麗多彩的網頁。
HTTP2.0
HTTP 1.1 在應用層以純文本的形式進行通信。每次通信都要帶完整的 HTTP 的頭,而且不考慮 pipeline 模式的話,每次的過程總是像上面描述的那樣一去一回。這樣在實時性、並發性上都存在問題。
為了解決這些問題,HTTP 2.0 會對 HTTP 的頭進行一定的壓縮,將原來每次都要攜帶的大量 key value 在兩端建立一個索引表,對相同的頭只發送索引表中的索引。
另外,HTTP 2.0 協議將一個 TCP 的連接中,切分成多個流,每個流都有自己的 ID,而且流可以是客戶端發往服務端,也可以是服務端發往客戶端。它其實只是一個虛擬的通道。流是有優先順序的。
HTTP 2.0 還將所有的傳輸信息分割為更小的消息和幀,並對它們採用二進位格式編碼。常見的幀有Header 幀,用於傳輸 Header 內容,並且會開啟一個新的流。再就是Data 幀,用來傳輸正文實體。多個 Data 幀屬於同一個流。
通過這兩種機制,HTTP 2.0 的客戶端可以將多個請求分到不同的流中,然後將請求內容拆成幀,進行二進位傳輸。這些幀可以打散亂序發送, 然後根據每個幀首部的流標識符重新組裝,並且可以根據優先順序,決定優先處理哪個流的數據。
假設我們的一個頁面要發送三個獨立的請求,一個獲取 css,一個獲取 js,一個獲取圖片 jpg。如果使用 HTTP 1.1 就是串列的,但是如果使用 HTTP 2.0,就可以在一個連接里,客戶端和服務端都可以同時發送多個請求或回應,而且不用按照順序一對一對應。
HTTP 2.0 其實是將三個請求變成三個流,將數據分成幀,亂序發送到一個 TCP 連接中。
HTTP 2.0 成功解決了 HTTP 1.1 的隊首阻塞問題,同時,也不需要通過 HTTP 1.x 的 pipeline 機制用多條 TCP 連接來實現並行請求與響應;減少了 TCP 連接數對伺服器性能的影響,同時將頁面的多個數據 css、js、 jpg 等通過一個數據鏈接進行傳輸,能夠加快頁面組件的傳輸速度。
TAG:小道視野 |