HTTP 報文是在應用程序之間發送的數據塊,這些數據塊將通過以文本形式的元信息開頭,用于 HTTP 協議交互。請求端(客戶端)的 HTTP 報文叫做請求報文,響應端(服務器端)的叫做響應報文。 HTTP 報文本身是由多行(用 CR+LF 作換行符)數據構成的字符串文本。
請求報文
HTTP 請求報文由請求行、請求頭、空行和請求包體(body)組成。如下圖所示:
真實示例:
GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: BIDUPSID=8B0207CE0B6364E5934651E84F17999B; PSTM=1619707475;
1.請求行
主要描述了客戶端想要如何操作服務端的資源;請求行由三部分構成:
- 請求方法:表示對資源期望進行何種操作,常用的如 GET、POST
- 請求目標:通常是一個 URL ,表明了要操作的資源。
- 版本號:表示報文使用的 HTTP 協議版本。
這三個部分通常使用空格(space)來分隔,最后要用 CRLF 換行表示結束。
GET / HTTP/1.1
這個請求行,結合之前的描述,意思就是“服務端妹子你好,我是客戶端蛋蛋,現在我想獲取網站根目錄的默認信息,我這邊用的協議版本是 1.1,麻煩你也要用這個版本回復我哦”
2.請求頭
HTTP的報文頭,報文頭包含若干個屬性,格式為“屬性名:屬性值”,服務端據此獲取客戶端的信息。與緩存相關的規則信息,均包含在header中,請求頭可大致分為四種類型:通用首部字段、請求首部字段、響應首部字段、實體首部字段。這里先簡單羅列,稍后做具體解釋。
3.請求體
請求體就是 HTTP 要傳輸的內容,HTTP 可以承載很多類型的數字數據:圖片、音頻、視頻、HTML 文檔等。
- 介紹響應報文
- 首部字段
- 介紹功能
響應報文
HTTP 響應報文由狀態行、響應頭部、空行和響應包體(body)組成。如下圖所示:
以請求 www.baidu.com為例:
HTTP/1.1 200 OK
Bdpagetype: 1
Bdqid: 0xfb0d743100040ad2
Cache-Control: private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Fri, 24 Dec 2021 08:20:44 GMT
Expires: Fri, 24 Dec 2021 08:20:44 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=17; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=35635_34439_35104_35628_35488_35436_35456_34584_35491_35584_35586_34873_35317_26350_35610_35562; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 1640334044050133761018090243032019634898
X-Frame-Options: sameorigin
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
1.狀態行
狀態行包含了 協議版本、狀態碼以及狀態描述。
- 協議版本:指明了報文使用的 HTTP 協議版本
- 狀態碼:狀態碼是一個三位數字,用來表示處理的結果,下面列出了狀態碼的類別:
- 狀態描述:這個是作為狀態碼的補充,是一段更詳細的文字,幫助人們理解原因。
2.響應頭部
和請求報文的請求頭類似,響應頭也由鍵值對組成,每行一對,鍵和值用英文冒號 : 分隔。響應頭域允許服務器傳遞不能放在狀態行的附加信息,這些域主要描述服務器的信息和Request-URI進一步的信息
3.響應包體
服務器返回給瀏覽器的響應信息,響應數據的格式是根據服務器來的,常見的響應數據格式有:text/html、application/json等。
常見的響應格式:
HTTP 首部字段
在 HTTP 的請求頭和響應頭中都是由首部字段來表示的,首部內容可以為客戶端和服務器分別處理請求和響應提供所需要的信息。
首部字段可以分為通用首部字段、請求首部字段、響應首部字段、實體首部字段。
通用首部字段
通用首部字段是指請求報文和響應報文都會使用到的首部字段。
先來看下都有哪些字段:
Cache-Control
通過指定 Cache-Control 的指令,就能操作緩存的工作機制。
一般在客戶端和服務端之間還存在一個緩存服務器,如果請求的資源在緩存服務器中有,就不會再請求源服務器,提高了請求響應的效率。
指令的參數可以多選,通過“,”分隔。
Cache-Control: private, max-age=0, no-cache
public 指令
Cache-Control: public
當使用 public 指令時,明確表明其他用戶也可以利用緩存。
private 指令
Cache-Control: private
當指定 private 指令后,響應只以特定的用戶作為對象,這與 public 指令的行為相反。
緩存服務器會對該特定用戶提供資源緩存的服務,對于其他用戶發送過來的請求,代理服務器則不會返回緩存。
no-cache 指令
Cache-Control: no-cache
使用 no-cache 指令可以防止從緩存中拿過期的數據。
在請求中如果包含該指令,則客戶端將不會接收緩存過的響應,中間的緩存服務器會把請求轉發給源服務器。
如果響應中包含該指令,緩存服務器會向源服務器進行資源有效期的確認,如果是過期的資源則不緩存。
no-store 指令
Cache-Control: no-store
該指令規定緩存不能在本地存儲請求或響應的任一部分。這里我們要和上面那個 no-cache 指令要區分開,no-store才是真正不進行緩存,no-cache 只是不對過期的資源進行緩存。
Connection
Connection 有兩個作用:控制不再轉發給代理的首部字段、管理持久連接。
- 控制不再轉發給代理的首部字段Connection: 不再轉發的首部字段名
- 管理持久連接
Connection: close
當服務器端想明確斷開連接時,則指定 Connection 首部字段的值為 Close。
Date
首部字段 Date 表明創建 HTTP 報文的日期和時間。
Trailer
首部字段 Trailer 會事先說明在報文主體后記錄了哪些首部字段。該首部字段可應用在 HTTP/1.1 版本分塊傳輸編碼時。
Transfer-Encoding
該字段規定了傳輸報文主體時采用的編碼方式。 HTTP/1.1 的傳輸編碼方式僅對分塊傳輸編碼有效。
請求首部字段
請求首部字段是從客戶端往服務器端發送請求報文中所使用的字段,用于補充請求的附加信息、客戶端信息、對響應內容相關的優先級等內容。
常用字段具體說明
Accept
Accept: text/html,application/xhtml+xml,application/xml;q=0.3
該字段可以通知服務器 客戶端能夠接收處理的媒體類型及優先級。
比如,如果瀏覽器不支持 PNG 圖片的顯示,那 Accept 就不指定 image/png ,而指定可處理的 image/gif 和 image/jpeg 等圖片類型。 若想要給顯示的媒體類型增加優先級,則使用 q= 來額外表示權重值。用分號(;)進行分隔。權重值 q 的范圍是 0~1(可精確到小數點 后 3 位),且 1 為最大值。不指定權重 q 值時,默認權重為 q=1.0。
Accept-Charset
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
通知服務器 客戶端支持的字符集及字符集的相對優先順序。
Accept-Encoding
Accept-Encoding: gzip, deflate
首部字段用來告知服務器 客戶端支持的內容編碼及內容編碼的優先級順序。可一次性指定多種內容編碼。
Accept-Language
Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
用來告知服務器 客戶端能夠處理的自然 語言集(指中文或英文等),以及自然語言集的相對優先級。可一次 指定多種自然語言集。
Authorization
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
首部字段 Authorization 是用來告知服務器,客戶端的認證信息(證書值)。
User-Agent
User-Agent: Mozilla/5.0 (windows NT 6.1; WOW64; rv:13.0)
首部字段 User-Agent 會將創建請求的瀏覽器和用戶代理名稱等信息傳 達給服務器。
由網絡爬蟲發起請求時,有可能會在字段內添加爬蟲作者的電子郵件地址。此外,如果請求經過代理,那么中間也很可能被添加上代理服務器的名稱。
響應首部字段
響應首部字段是由服務器端向客戶端返回響應報文中所使用的字段,用于補充響應的附加信息、服務器信息,以及對客戶端的附加要求等信息。
Accept-Ranges
Accept-Ranges: bytes 當不能處理范圍請求時,Accept-Ranges: none
用來告知客戶端服務器是否能處理范圍請 求,以指定獲取服務器端某個部分的資源。
Age
Age: 600
Age 能告知客戶端,源服務器在多久前創建了響應。字段值的單位為秒。
Location
Location: http://www.usagidesign.jp/sample.html
該字段可以將響應接收方引導至某個與請求 URI 位置 不同的資源。
基本上,該字段會配合 3xx :Redirection 的響應,提供重定向的 URI。
Retry-After
Retry-After: 120
告知客戶端應該在多久之后再次發送請求。主要 配合狀態碼 503 Service Unavailable 響應,或 3xx Redirect 響應一起使 用。
Server
Server: Apache/2.2.17 (Unix)
告知客戶端當前服務器上安裝的 HTTP 服務器應用程序的信息。
實體首部字段
實體首部字段是包含在請求報文和響應報文中的實體部分所使用的首部,用于補充內容的更新時間等與實體相關的信息。
Allow
Allow: GET, HEAD
用于通知客戶端能夠支持 Request-URI 指定資源的所有 HTTP 方法。
Content-Encoding
Content-Encoding: gzip
會告知客戶端服務器對實體的主體部分選用的內容編碼方式。
Content-Language
Content-Language: zh-CN
首部字段 Content-Language 會告知客戶端,實體主體使用的自然語言。
Content-Length
Content-Length: 15000
表明了實體主體部分的大小(單位是字 節)。
Content-Type
Content-Type: text/html; charset=UTF-8
說明了實體主體內對象的媒體類型。