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首部欄位具備如下兩個作用
- 控制不再轉發給代理的首部欄位
- 管理持久連線
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 指令碼進
行動態資料處理時,該值有可能會變成資料最終修改時的時間。
20. Set-Cookie
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,到這裡本文要介紹的相關知識也就結束了。對於文章開頭提出的三個問題不知道你現在有沒有清楚呢。最後希望小夥伴可以在下方留言評論(對於文章的文字排版,寫作技巧,相關內容都可以相互交流學習)