HTTP 消息


HTTP 消息

圖片來自 unsplash

年後第一篇,在家待著效率實在不高。最近在忙著總結前端面試相關的技術文檔,等完善度達到70%或者更高的時候我將會開放出來!!!

HTTP 對前端有多重要這不用多說,這篇文章只介紹了 HTTP 消息的內容組成,如果下面的內容你還不熟悉,這說明你需要加把勁了!!

HTTP 消息由採用 ASCII 編碼 的多行文本構成。在 HTTP/1.1 及早期版本中,這些消息通過連接公開地發送。在 HTTP/2 中,為了優化和性能方面的改進,曾經可人工閱讀的消息被分到多個 HTTP 幀中。

來看看請求和響應實際是什麼樣的:

HTTP 消息

HTTP 請求

HTTP 消息

HTTP 響應

HTTP 消息組成

HTTP 請求和響應具有相似的結構,由以下部分組成︰

  1. 一行起始行用於描述要執行的請求,或者是對應的狀態,成功或失敗。這個起始行總是單行的;
  2. 一個可選的HTTP 頭集合指明請求或描述消息正文;
  3. 一個空行指示所有關於請求的元數據已經發送完畢;
  4. 一個可選的包含請求相關數據的正文 (比如 HTML 表單內容), 或者響應相關的文檔。正文的大小由起始行的 HTTP 頭來指定;

起始行和 HTTP 消息中的 HTTP 頭統稱為請求頭,而其有效負載被稱為消息正文。

HTTP 消息

HTTP 消息

HTTP 請求

起始行

HTTP 請求是由客戶端發出的消息,用來使服務器執行動作。起始行 (start-line) 包含三個元素:

  1. HTTP 方法;
  2. 請求目標 (request target),通常是一個 URL,或者是協議、端口和域名的絕對路徑;
  3. HTTP 版本,定義了剩餘報文的結構,作為對期望的響應版本的指示符;

請求頭

不區分大小寫的字符串,緊跟著冒號 (:) 和一個結構取決於 header 的值。 整個 header(包括值)由一行組成,這一行可以相當長。

請求頭分為幾組:

  1. 通用頭(General headers),例如 Via,適用於整個報文;
  2. 請求頭(Request headers),例如 User-Agent,Accept-Type,通過進一步的定義(例如 Accept-Language),或者給定上下文(例如 Referer),或者進行有條件的限制 (例如 If-None) 來修改請求;
  3. 實體頭(Entity headers),例如 Content-Length,適用於請求的 body。顯然,如果請求中沒有任何 body,則不會發送這樣的頭文件。
HTTP 消息

HTTP header

請求體

請求的最後一部分是它的請求體(body)。不是所有的請求都有一個 body:例如獲取資源的請求,GET,HEAD,DELETE 和 OPTIONS,通常它們不需要 body。有些請求將數據發送到服務器以便更新數據:常見的的情況是 POST 請求(包含 HTML 表單數據)。

HTTP 響應

起始行

HTTP 響應的起始行被稱作狀態行(status line),包含以下信息:

  1. 協議版本,通常為 HTTP/1.1
  2. 狀態碼 (status code);
  3. 狀態文本 (status text);

一個典型的狀態行是這樣的:

<code>HTTP/1.1 404 Not Found
/<code>

響應頭

不區分大小寫的字符串,緊跟著的冒號 (:) 和一個結構取決於 header 類型的值。 整個 header(包括其值)表現為單行形式。

這些響應頭可以分為幾組:

  1. 通用頭(General headers),例如 Via,適用於整個報文;
  2. 返回頭(Response headers),例如 Vary 和 Accept-Ranges,提供其它不符合狀態行的關於服務器的信息
  3. 實體頭(Entity headers),例如 Content-Length,適用於請求的 body。顯然,如果請求中沒有任何 body,則不會發送這樣的頭文件;
HTTP 消息

HTTP 響應

響應體

響應的最後一部分是響應體(body)。不是所有的響應都有 body:具有狀態碼 (如 201 或 204) 的響應,通常不會有 body。

Body 大致可分為三類:

  1. Single-resource bodies,由已知長度的單個文件組成。該類型 body 由兩個 header 定義:Content-Type 和 Content-Length;
  2. Single-resource bodies,由未知長度的單個文件組成,通過將 Transfer-Encoding 設置為 chunked 來使用 chunks 編碼。
  3. Multiple-resource bodies,由多部分 body 組成,每部分包含不同的信息段。但這是比較少見的;

總結

HTTP 請求體格式

<code>POST /query HTTP/1.1
Host: web-api.juejin.im
Connection: keep-alive
Content-Length: 132
Origin: https://juejin.im
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Content-Type: application/json
Accept: */*

Referer: https://juejin.im/timeline
Accept-Encoding: gzip
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7

{"variables":{"type":"ARTICLE","since":"2019-12-17T02:22:52.801Z"},"extensions":{"query":{"id":"0d2f86267cfa529141a196314c2038e2"}}}
/<code>

HTTP 響應體格式

<code>HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Tue, 18 Feb 2020 04:28:54 GMT
Content-Type: application/json
Content-Length: 56
Connection: close
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type,X-Agent,X-Token,X-Legacy-Token,X-Legacy-Uid,X-Legacy-Device-Id,X-Legacy-New-Token,X-Request-Id
Access-Control-Max-Age: 86400

{"data":{"followingActivityFeed":{"newItemCount":348}}}
/<code>

補充

HTTP/1.x 報文有一些性能上的缺點:

  1. Header 不像 body,它不會被壓縮;
  2. 兩個報文之間的 header 通常非常相似,但它們仍然在連接中重複傳輸;
  3. 無法複用。當在同一個服務器打開幾個連接時:TCP 熱連接比冷連接更加有效;

HTTP2 的解決辦法:

HTTP/2 引入了一個額外的步驟:它將 HTTP/1.x 消息分成幀並嵌入到流 (stream) 中數據幀和報頭幀分離,這將允許報頭壓縮。將多個流組合,這是一個被稱為多路複用 (multiplexing) 的過程,它允許更有效的底層 TCP 連接。

HTTP 消息

HTTP 幀現在對 Web 開發人員是透明的。在 HTTP/2 中,這是一個在 HTTP/1.1 和底層傳輸協議之間附加的步驟。Web 開發人員不需要在其使用的 API 中做任何更改來利用 HTTP 幀;當瀏覽器和服務器都可用時,HTTP/2 將被打開並使用。



分享到:


相關文章: