1. 程式人生 > >HTTP首部欄位完全解析

HTTP首部欄位完全解析

http協議是前端開發人員最常接觸到的網路協議。在開發過程中,尤其是除錯過程中避免不了需要去分析http請求的詳細資訊。在這其中頭部欄位提供的資訊最多,比如通過響應狀態碼我們可以直觀的看到響應的大致狀態。那麼你是否清楚http首部欄位都有哪些,具體含義是什麼,可選值又有哪些呢?看完下面的內容,我相信對於這幾個問題你就會迎刃而解。

http協議用於互動的資訊被稱為HTTP報文。請求端(客戶端)的HTTP報文叫做請求報文,響應端(伺服器端)的HTTP報文叫做響應報文。HTTP報文大致可以分為報文首部和報文主題兩部分。我們來看下請求報文和響應報文的結構。

從上圖我們可以看出,請求報文和響應報文的首部內容由以下資料組成。

請求行

包含用於請求的方法,請求 URI 和 HTTP 版本。

狀態行

包含表明響應結果的狀態碼,原因短語和 HTTP 版本。

首部欄位

包含表示請求和響應的各種條件和屬性的各類首部。

下面我們重點來看下首部欄位的一些資訊,並且對最常用到的首部欄位的含義及可選值都有哪些,分別代表什麼意思進行講解。
http首部欄位型別根據實際用途被分為以下4種類型:

通用首部欄位(General Header Fields)

請求報文和響應報文兩方都會使用的首部。

請求首部報文(Request Headers Fields)

從客戶端向服務端傳送請求報文時使用的首部。補充了請求的附加內容,客戶端資訊,響應內容相關優先順序等資訊。

響應首部欄位(Response Header Fields)

從伺服器端向客戶端返回響應報文時使用的首部。補充了響應的附加內容,也會要求客戶端附加額外的內容資訊。

實體首部欄位(Entity Header Fields)

針對請求報文和響應報文的實體部分使用的首部。補充了資源內容更新時間等與實體相關的資訊。


其中http/1.1規範定義了47種首部欄位,下面我們按照以上的四個大類對這47種欄位進行一個簡要解釋:

通用首部欄位

首部欄位名 說明
Cache-Control 控制快取的行為
Connection 連線的管理
Date 建立報文的日期時間
Pragma 報文指令
Trailer 報文末端的首部一覽
Transfer-Encoding 指定報文主體的傳輸編碼方式
Upgrade 升級為其他協議
Via 代理伺服器的相關資訊
Warning 錯誤通知

請求首部欄位

首部欄位名 說明
Accept 使用者代理可處理的媒體型別
Accept-Charset 優先的字符集
Accept-Encoding 優先的內容編碼
Accept-Language 優先的語言(自然語言)
Authorization Web認證資訊
Expect 期待伺服器的特定行為
From 使用者的電子郵箱地址
Host 請求資源所在伺服器
If-Match 比較實體標記(ETag)
If-Modified-Since 比較資源的更新時間
If-None-Match 比較實體標記(與 If-Match 相反)
If-Range 資源未更新時傳送實體 Byte 的範圍請求
If-Unmodified-Since 比較資源的更新時間(與If-Modified-Since相反)
Max-Forwards 最大傳輸逐跳數
Proxy-Authorization 代理伺服器要求客戶端的認證資訊
Range 實體的位元組範圍請求
Referer 對請求中URI的原始獲取方
TE 傳輸編碼的優先順序
User-Agent HTTP客戶端程式的資訊

響應首部欄位

首部欄位名 說明
Accept-Ranges 是否接受位元組範圍請求
Age 推算資源建立經過時間
ETag 資源的匹配資訊
Location 令客戶端重定向至指定URI
Proxy-Authenticate 代理伺服器對客戶端的認證資訊
Retry-After 對再次發起請求的時機要求
Server HTTP伺服器的安裝資訊
Vary 代理伺服器快取的管理資訊
WWW-Authenticate 伺服器對客戶端的認證資訊

實體首部欄位

首部欄位名 說明
Allow 資源可支援的HTTP方法
Content-Encoding 實體主體適用的編碼方式
Content-Language 實體主體的自然語言
Content-Length 實體主體的大小(單位:位元組)
Content-Location 替代對應資源的URI
Content-MD5 實體主體的報文摘要
Content-Range 實體主體的位置範圍
Content-Type 實體主體的媒體型別
Expires 實體主體過期的日期時間
Last-Modified 資源的最後修改日期時間

常用首部欄位分析:

1. Cache-Control 指令一覽

可用的指令按請求和響應分類如下所示:

快取請求指令:

指令 引數 說明
no-cache 強制向原伺服器再次驗證
no-store 不快取請求或響應的任何內容
max-age = [ 秒] 必須 響應的最大Age值
max-stale( = [ 秒]) 可省略 接收已過期的響應
min-fresh = [ 秒] 必需 期望在指定的時間內的響應仍有效
no-transform 代理不可更改媒體型別
only-if-cached 代理不可更改媒體型別
cache-extension - 新指令標記(token)

快取響應指令:

指令 引數 說明
public 可向任意方提供響應的快取
private 可省略 僅向特定使用者返回響應
no-cache 可省略 快取前必需先確認其有效性
no-store 不快取請求或響應的任何內容
no-transform 代理不可更改媒體型別
must-revalidate 可快取但必須再向源伺服器進行確認
proxy-revalidate 要求中間快取伺服器對快取的響應有效性再進行確認
max-age=[秒] 必需 響應的最大Age值
s-maxage=[秒] 必需 公共快取伺服器響應的最大Age值
cache-extension - 新指令標記(token)

從字面意思上很容易把 no-cache 誤解成為不快取,但事實上 no-cache 代表不緩
存過期的資源,快取會向源伺服器進行有效期確認後處理資源,也許稱為 do-notserve-
from-cache-without-revalidation 更合適。no-store 才是真正地不進行快取,請
讀者注意區別理解

2. Connection

Connection首部欄位具備如下兩個作用

  1. 控制不再轉發給代理的首部欄位
  2. 管理持久連線

HTTP/1.1 版本的預設連線都是持久連線。為此,客戶端會在持
久連線上連續傳送請求。當伺服器端想明確斷開連線時,則指定
Connection 首部欄位的值為 Close。

Date

首部欄位Date表明建立HTTP報文的日期和時間。

3. Pragma

Pragma是HTTP/1.1之前版本的歷史遺留欄位,僅作為與HTTP/1.0的向後相容而定義。

規範定義的形式唯一,如下所示:

Pragma: no-cache

該首部欄位屬於通用首部欄位,但只用在客戶端傳送的請求中。客戶端會要求所有的中間伺服器不返回快取的資源。

所有的中間伺服器如果都能以 HTTP/1.1 為基準,那直接採用 Cache-
Control: no-cache 指定快取的處理方式是最為理想的。但要整體掌握
全部中間伺服器使用的 HTTP 協議版本卻是不現實的。因此,傳送的
請求會同時含有下面兩個首部欄位。

Cache-Control: no-cache
Pragma: no-cache

4. Upgrade

首部欄位 Upgrade 用於檢測 HTTP 協議及其他協議是否可使用更高的
版本進行通訊,其引數值可以用來指定一個完全不同的通訊協議。

使用首部欄位 Upgrade 時,還需要額外指定Connection:Upgrade。

5. Accept

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

Accept 首部欄位可通知伺服器,使用者代理能夠處理的媒體型別及媒體
型別的相對優先順序。可使用 type/subtype 這種形式,一次指定多種媒
體型別。

6. Accept-Charset

Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

Accept-Charset 首部欄位可用來通知伺服器使用者代理支援的字符集及
字符集的相對優先順序。另外,可一次性指定多種字符集。與首部字
段 Accept 相同的是可用權重 q 值來表示相對優先順序

7. Accept-Encoding

Accept-Encoding: gzip, deflate

Accept-Encoding 首部欄位用來告知伺服器使用者代理支援的內容編碼及
內容編碼的優先順序順序。可一次性指定多種內容編碼。

下面試舉出幾個內容編碼的例子。

  • gzip

由檔案壓縮程式 gzip(GNU zip)生成的編碼格式
(RFC1952),採用 Lempel-Ziv 演算法(LZ77)及 32 位迴圈冗餘
校驗(Cyclic Redundancy Check,通稱 CRC)。

  • compress

    由 UNIX 檔案壓縮程式 compress 生成的編碼格式,採用 Lempel-
    Ziv-Welch 演算法(LZW)。

  • deflate

    組合使用 zlib 格式(RFC1950)及由 deflate 壓縮演算法
    (RFC1951)生成的編碼格式。

  • identity

    不執行壓縮或不會變化的預設編碼格式

採用權重 q 值來表示相對優先順序,這點與首部欄位 Accept 相同。另
外,也可使用星號(*)作為萬用字元,指定任意的編碼格式。

8. Accept-Language

Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3

首部欄位 Accept-Language 用來告知伺服器使用者代理能夠處理的自然
語言集(指中文或英文等),以及自然語言集的相對優先順序。可一次
指定多種自然語言集。

和 Accept 首部欄位一樣,按權重值 q 來表示相對優先順序。在上述圖
例中,客戶端在伺服器有中文版資源的情況下,會請求其返回中文版
對應的響應,沒有中文版時,則請求返回英文版響應。

9. If-Match

形如 If-xxx 這種樣式的請求首部欄位,都可稱為條件請求。伺服器接
收到附帶條件的請求後,只有判斷指定條件為真時,才會執行請求。

首部欄位 If-Match,屬附帶條件之一,它會告知伺服器匹配資源所用
的實體標記(ETag)值。這時的伺服器無法使用弱 ETag 值。(請參
照本章有關首部欄位 ETag 的說明)

伺服器會比對 If-Match 的欄位值和資源的 ETag 值,僅當兩者一致
時,才會執行請求。反之,則返回狀態碼 412 Precondition Failed 的響
應。

還可以使用星號(*)指定 If-Match 的欄位值。針對這種情況,服務
器將會忽略 ETag 的值,只要資源存在就處理請求。

10. Referer

Referer: http://172.30.1.34:4200/

首部欄位 Referer 會告知伺服器請求的原始資源的 URI。

11. User-Agent

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36

首部欄位 User-Agent 會將建立請求的瀏覽器和使用者代理名稱等資訊傳
達給伺服器。

12. Age

首部欄位 Age 能告知客戶端,源伺服器在多久前建立了響應。欄位值
的單位為秒。

若建立該響應的伺服器是快取伺服器,Age 值是指快取後的響應再次
發起認證到認證完成的時間值。代理建立響應時必須加上首部欄位
Age。

13. ETag

首部欄位 ETag 能告知客戶端實體標識。它是一種可將資源以字串
形式做唯一性標識的方式。伺服器會為每份資源分配對應的 ETag
值。

14. Location

使用首部欄位 Location 可以將響應接收方引導至某個與請求 URI 位置
不同的資源。

基本上,該欄位會配合 3xx :Redirection 的響應,提供重定向的
URI。

幾乎所有的瀏覽器在接收到包含首部欄位 Location 的響應後,都會強
制性地嘗試對已提示的重定向資源的訪問。

15. Content-Encoding

首部欄位 Content-Encoding 會告知客戶端伺服器對實體的主體部分選
用的內容編碼方式。內容編碼是指在不丟失實體資訊的前提下所進行
的壓縮。

16. Content-Language

Content-Language: zh-CN

首部欄位 Content-Language 會告知客戶端,實體主體使用的自然語言
(指中文或英文等語言)。

17. Content-Length

Content-Length: 15000

首部欄位 Content-Length 表明了實體主體部分的大小(單位是字
節)。對實體主體進行內容編碼傳輸時,不能再使用 Content-Length
首部欄位

18. Content-Type

Content-Type: text/html; charset=UTF-8

首部欄位 Content-Type 說明了實體主體內物件的媒體型別。和首部字
段 Accept 一樣,欄位值用 type/subtype 形式賦值。

19. Last-Modified

Last-Modified: Wed, 21 Aug 2019 06:18:22 GMT

首部欄位 Last-Modified 指明資源最終修改的時間。一般來說,這個
值就是 Request-URI 指定資源被修改的時間。但類似使用 CGI 指令碼進
行動態資料處理時,該值有可能會變成資料最終修改時的時間。

Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31

伺服器設定客戶端cookie資訊,以便管理客戶端狀態。

  • HttpOnly 屬性

    Cookie 的 HttpOnly 屬性是 Cookie 的擴充套件功能,它使 JavaScript 指令碼
    無法獲得 Cookie。其主要目的為防止跨站指令碼攻擊(Cross-site
    scripting,XSS)對 Cookie 的資訊竊取。

傳送指定 HttpOnly 屬性的 Cookie 的方法如下所示。

Set-Cookie: name=value; HttpOnly

通過上述設定,通常從 Web 頁面內還可以對 Cookie 進行讀取操作。
但使用 JavaScript 的 document.cookie 就無法讀取附加 HttpOnly 屬性後
的 Cookie 的內容了。因此,也就無法在 XSS 中利用 JavaScript 劫持
Cookie 了。

以上所列出的首部欄位都是基於HTTP/1.1,到這裡本文要介紹的相關知識也就結束了。對於文章開頭提出的三個問題不知道你現在有沒有清楚呢。最後希望小夥伴可以在下方留言評論(對於文章的文字排版,寫作技巧,相關內容都可以相互交流學習)