HTTP 的基本結構


HTTP 協議與 TCP/UDP 類似,需要在實際傳輸的數據前附加一些頭數據。不過與 TCP/UDP 不同的是,HTTP 協議是一個“純文本”協議,頭部數據都是 ASCII 碼的文本,可以直接閱讀。

報文結構

HTTP 協議的請求報文和響應報文基本相同,由三大部分組成:

  1. 起始行(start line):描述請求和響應的基本信息;
  2. 頭部字段集合(header):使用 key-value 形式更詳細的說明報文;
  3. 消息正文(entity):實際傳輸的數據,可以是文本、圖片、視頻等。

其中前兩部分起始行和頭部字段經常合稱為“請求頭”或“響應頭”,消息正文又稱為“body”。

HTTP 協議規定報文必須有 header,可以沒有 body,而且在 header 之后必須要有一個“空行(CRLF)”。

drawing

請求行

GET / HTTP/1.1

請求行由三部分構成:

  1. 請求方法:如 GET、POST,表示對資源的操作;
  2. 請求目標:通常是一個 URI,標記了請求方法要操作的資源;
  3. 版本號:表示報文使用的 HTTP 協議版本。

這三部分通常使用空格(space)來分隔,最后要用 CRLF 換行表示結束。

drawing

狀態行

HTTP/1.1 200 OK

響應報文中的起始行稱為“狀態行”,意思是服務器響應的狀態。

狀態行也是由三部分構成:

  1. 版本號:表示報文使用的 HTTP 協議版本;
  2. 狀態碼:一個三位數,表示處理的結果。如 200 是成功,500 是服務器錯誤。
  3. 原因:作為數字狀態碼補充,是更詳細的解釋。
drawing

頭部字段

請求行或狀態行再加上頭部字段集合就構成了 HTTP 報文里完整的請求頭或響應頭。
頭部字段是 key-value 的形式,key 和 value 之間用“:”分隔,最后用 CRLF 換行表示字段結束。
HTTP 頭字段非常靈活,不僅可以使用標准里的 Host、Connection 等已有頭,還可以任意添加自定義頭,這給 HTTP 協議帶來了無限拓展可能。

常用頭字段

基本可以分為四大類:

  1. 通用字段:在請求頭和響應頭里都可以出現;
  2. 請求字段:只能出現在請求頭里,進一步說明請求信息或額外的附加條件;
  3. 響應字段:只能出現在響應頭里,補充說明響應報文的信息;
  4. 實體字段:它實際上屬於通用字段,但專門描述 body 的額外信息。

Host

Host 屬於請求字段,只能出現在請求頭里,同時也是唯一一個 HTTP/1.1 規范里要求必須出現的字段。
Host 字段告訴服務器這個請求該由哪個主機來處理,當一台計算機上托管了多個虛擬主機的時候,服務器端就需要用 Host 字段來選擇,有點像一個簡單的“路由重定向”。

User-Agent

User-Agent 屬於請求字段,只出現在請求頭里。描述發起 HTTP 請求的客戶端,服務器可以依據它來返回最適合此瀏覽器顯示的頁面。

Date

Date 是一個通用字段,但通常出現在響應頭里,表示 HTTP 報文創建的時間,客戶端可以使用這個時間再搭配其他字段決定緩存策略。

Server

Server 是響應字段,只能出現在響應頭里。它告訴客戶端當前正在提供 Web 服務的軟件名稱和版本號。這個字段不是必須要出現的,因為這會把服務器的一部分信息暴露給外界。所以,有的網站響應頭里要么沒有這個字段,要么就給出一個完全無關的信息。

Content-length

Content-length 表示報文里 body 的長度,也就是請求頭或響應頭空行后面數據的長度。服務器看到這個字段,就知道了后續有多少數據,可以直接接收。如果沒有這個字段,那么 body 就是不定長的,需要使用 chunked 方式分段傳輸。

問題:

  1. 如果在拼 HTTP 報文的時候,在頭字段后多加了一個 CRLF,導致出現了一個空行,會發生什么?
    答:在 header 下面第一個空行以后都會被當作 body 處理

  2. 頭字段“:”后面的空格可以有多個,那么為什么絕大多數情況下都只使用一個空格呢?
    答:頭部多一個空格就會多一個傳輸的字節,去掉無用的信息,保證傳輸的頭部字節數盡量小。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM