9 HTTP報文是什麼樣子的

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

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

這其中前兩部分起始行和頭部字段經常又合稱爲“請求頭”或“響應頭”,消息正文又稱爲“實體”,但與“header”對應,很多時候就直接稱爲“body”。

HTTP 協議規定報文必須有 header,但可以沒有 body,而且在 header 之後必須要有一個“空行”,也就是“CRLF”,十六進制的“0D0A”。

所以,一個完整的 HTTP 報文就像是下圖的這個樣子,注意在 header 和 body 之間有一個“空行”。說到這裏,我不由得想起了一部老動畫片《大頭兒子和小頭爸爸》,你看,HTTP 的報文結構像不像裏面的“大頭兒子”?

image

看一下我們之前用 Wireshark 抓的包吧。

image

請求行

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

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

image

還是用 Wireshark 抓包的數據來舉例

GET / HTTP/1.1

狀態行

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

image

看一下上一講裏 Wireshark 抓包裏的響應報文,狀態行是:

HTTP/1.1 200 OK

頭部字段

image

image

請求頭和響應頭的結構是基本一樣的,唯一的區別是起始行,所以我把請求頭和響應頭裏的字段放在一起介紹。

頭部字段是 key-value 的形式,key 和 value 之間用“:”分隔,最後用 CRLF 換行表示字段結束。比如在“Host: 127.0.0.1”這一行裏 key 就是“Host”,value就是“127.0.0.1”。

HTTP 頭字段非常靈活,不僅可以使用標準裏的 Host、Connection 等已有頭,也可以任意添加自定義頭,這就給HTTP 協議帶來了無限的擴展可能。

不過使用頭字段需要注意下面幾點:

  1. 字段名不區分大小寫,例如“Host”也可以寫成“host”,但首字母大寫的可讀性更好;
  2. 字段名裏不允許出現空格,可以使用連字符“-”,但不能使用下劃線“_”。例如,“test-name”是合法的字段名,而“test name”“test_name”是不正確的字段名;
  3. 字段名後面必須緊接着“:”,不能有空格,而“:”後的字段值前可以有多個空格;
  4. 字段的順序是沒有意義的,可以任意排列不影響語義;
  5. 字段原則上不能重複,除非這個字段本身的語義允許,例如 Set-Cookie。

常用頭字段

HTTP 協議規定了非常多的頭部字段,實現各種各樣的功能,但基本上可以分爲四大類:

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

首先要說的是 Host 字段,它屬於請求字段,只能出現在請求頭裏,它同時也是唯一一個 HTTP/1.1 規範裏要求必須出現的字段,也就是說,如果請求頭裏沒有 Host,那這就是一個錯誤的報文。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章