上一篇文章我們大致講解了一下 HTTP 的基本特徵和使用,大家反響很不錯,那麼本篇文章我們就來深究一下 HTTP 的特性。我們接著上篇文章沒有說完的 HTTP 標頭繼續來介紹(此篇文章會介紹所有標頭的概念,但沒有深入底層)
HTTP 標頭
先來回顧一下 HTTP1.1 標頭都有哪幾種
HTTP 1.1 的標頭主要分為四種,通用標頭
、實體標頭
、請求標頭
、響應標頭
,現在我們來對這幾種標頭進行介紹
通用標頭
HTTP 通用標頭之所以這樣命名,是因為與其他三個類別不同,它們不是限定於特定種類的訊息或者訊息元件(請求,響應或訊息實體)的。HTTP 通用標頭主要用於傳達有關訊息本身的資訊,而不是它所攜帶的內容。它們提供一般資訊並控制如何處理和處理訊息。
儘管通用標頭不會限定於是請求還是響應報文,但是某些通用標頭大部分或全部用於一種特定型別的請求中。也就是說,如果某個通用標頭出現在請求報文中,那麼大部分通用標頭都會顯示在該請求報文中。響應報文也是一樣的。
先列出來一個清單,講明我們都需要介紹哪些通用標頭
- Cache-Control
- Connection
- Date
- Pragma
- Trailer
- Transfer-Encoding
- Upgrade
- Via
- Warning
Cache-Control
快取(Cache)
是計算機領域裡的一個重要概念,是優化系統效能的利器。不僅計算機中的 CPU 為了提高指令執行效率從而選擇使用暫存器作為輔助,計算機網路同樣存在快取,下面我們就來介紹一下計算機網路中的快取。
Cache-Control
是通用標頭的指令,它能夠管理如何對 HTTP 的請求或者響應使用快取。
因為計算機網路中是可以有第三者
出現的,也就是快取伺服器
,這個指令通過影響請求/響應
中的快取伺服器從而達到控制快取的目的;不僅有快取伺服器,還有瀏覽器內部快取也會影響鏈路的快取。
這個標頭中可以出現許多單獨的指令,其詳細資訊可以在 RFC 2616 中找到,即使這是常規標頭,某些指令也只能出現在請求或響應中。下表提供了一個 Cache-Control 選項的總結並告訴你如何去使用
請注意,在 Cache-Control 標頭中只能出現一個指令,但是在訊息中可以出現多個這樣的標頭。
上面這個表格其實會有四種分類
可快取性
: 它們分別是no-cache
、no-store
、private
和public
快取有效性時間
: 它們分別是max-age
、s-maxage
、max-stale
、min-fresh
重新驗證並重新載入
: 它們分別是must-revalidate
和proxy-revalidate
其他
: 它們分別是only-if-cached
和no-transform
分別對錶格中的內容進行一下詳細介紹
no-cache
no-cache
很容易和 no-store
混淆,一般都會把 no-cache
認為是不快取,其實不是這樣。
使用 no-cache 指令的目的是為了防止從快取中返回過期的資源,例如下圖所示
Cache-Control: no-cache
複製程式碼
舉個例子你就明白了,No-Cache 就相當於是吃著碗裡的,佔著鍋裡的
,如果鍋裡還有新的肉片,就先吃鍋裡的,如果鍋裡沒有新的,再吃自己的,這裡鍋裡的
就相當於是源伺服器產生的,碗裡的
就相當於是快取的。
no-store
no-store
才是真正意義上的不快取
,每次伺服器接受到客戶端的請求後,都會返回最新的資源給客戶端。
Cache-Control: no-store
複製程式碼
max-age
max-age
可以用在請求或者響應中,當客戶端傳送帶有 max-age 的指令時,快取伺服器會判斷自己快取時間的數值和 max-age 的大小,如果比 max-age 小,那麼快取有效,可以繼續給客戶端返回快取的資料,如果比 max-age 大,那麼快取伺服器將不能返回給客戶端快取的資料。
Cache-Control: max-age=60
複製程式碼
如果 max-age = 0
,那麼快取伺服器將會直接把請求轉發到伺服器
Cache-Control: max-age=0
複製程式碼
注意:這個 max-age 的值是相對於請求時間的
must-revalidate
表示一旦資源過期,快取就必須在原始伺服器上沒有成功驗證的情況下才使用其過期的資料。
Cache-Control: must-revalidate
複製程式碼
no-store
、no_cache
、 must-revalidate
和 max-age
可以一起看,下面是一個這四個標頭的流程圖
public
public
屬性只出現在客戶端響應中,表示響應可以被任何快取所快取。在計算機網路中,分為兩種快取,共享快取和私有快取,如下所示
Cache-Control: public
複製程式碼
private
當指定 private
指令後,響應只以特定的使用者作為物件,這與 public
的用法相反,快取伺服器只對特定的客戶端進行快取,其他客戶端傳送過來的請求,快取伺服器則不會返回快取。
Cache-Control: private
複製程式碼
s-maxage
s-maxage
指令的功能和 max-age
指令的功能相同,不同點之處在於 s-maxage 不能用於私有快取,只能用於多使用者使用的公共伺服器,對於同一使用者的重複請求和響應來說,這個指令沒有任何作用。
Cache-Control: s-maxage=60
複製程式碼
min-fresh
min-fresh
只能出現在請求中,min-fresh
要求快取伺服器返回 min-fresh 時間內的快取資料。例如 Cache-Control:min-fresh=60
,這就要求快取伺服器傳送60秒內的資料。
Cache-Control: min-fresh=60
複製程式碼
max-stable
max-stable
只能出現在請求中,表示客戶端會接受快取資料,即使過期也照常接收。
Cache-Control: max-stable=60
複製程式碼
only-if-cached
這個標頭只能出現在請求中,使用 only-if-cached
指令表示客戶端僅在快取伺服器本地快取目標資源的情況下才會要求其返回。
Cache-Control: only-if-cached
複製程式碼
proxy-revalidate
proxy-revalidate
指令要求所有的快取伺服器在接收到客戶端帶有該指令的請求返回響應之前,必須再次驗證快取的有效性。
Cache-Control: proxy-revalidate
複製程式碼
no-transform
使用 no-transform
指令規定無論是在請求還是響應中,快取都不能改變實體主體的媒體型別。
Cache-Control: no-transform
複製程式碼
Connection
HTTP 協議使用 TCP 來管理連線方式,主要有兩種連線方式,永續性連線
和 非永續性連線
。
永續性連線
永續性連線指的是一次會話完成後,TCP 連線並未關閉,第二次再次傳送請求後,就不再需要建立 TCP 連線,而是可以直接進行請求和響應。它的一般表示形式如下
Connection: keep-alive
複製程式碼
從 HTTP 1.1 開始,預設使用永續性連線。
keep-alive
也是一個通用標頭,一般 Connection 都會和 keep-alive 一起使用,keep-alive 有兩個引數,一個是 timeout
;另一個是 max
,它們的主要表現形式如下
Connection: Keep-Alive
Keep-Alive: timeout=5, max=1000
複製程式碼
-
timeout: 指的是空閒連線必須開啟的最短時間,也就是說這次請求的連線時間不能少於5秒,
-
max: 指的是在連線關閉之前伺服器所能夠收到的最大請求數。
非永續性連線
非永續性連線表示一次會話請求/響應後關閉連線的方式。HTTP 1.1 之前使用的連線都是非持久連線,也就是
Connection: close
複製程式碼
Date
Date 是一個通用標頭,它可以出現在請求標頭和響應標頭中,它的基本表示如下
Date: Wed, 21 Oct 2015 07:28:00 GMT
複製程式碼
表示的是格林威治標準時間,這個時間要比北京時間慢八個小時
Pragma
Pragma
是 http 1.1 之前版本的歷史遺留欄位,僅作為與 http 的向後相容而定義。它的一般形式如下
Pragma: no-cache
複製程式碼
只用於客戶端傳送的請求中。客戶端會要求所有的中間伺服器不返回快取的資源。
如果所有的中間伺服器都以實現 HTTP /1.1為標準,那麼直接使用 Cache-Control: no-cache 即可,如果不是的話,就要包含兩個欄位,如下
Cache-Control: no-cache
Pragma: no-cache
複製程式碼
Trailer
首部欄位 Trailer 會事先說明在報文主體後記錄了哪些首部欄位。該首部欄位可應用在 HTTP/1.1 版本分塊傳輸編碼時。一般用法如下
Transfer-Encoding: chunked
Trailer: Expires
複製程式碼
以上用例中,指定首部欄位 Trailer 的值為 Expires,在報文主體之後(分塊長度 0 之後)出現了首部欄位 Expires。
Transfer-Encoding
Transfer-Encoding 屬於內容協商的範疇,下面會具體介紹一下內容協商,現在先做個預告:Transfer-Encoding
規定了傳輸報文所採用的編碼方式
注意:HTTP 1.1 的傳輸編碼方式僅對分塊傳輸有效,但是 HTTP 2.0 就不再支援分塊傳輸,而提供了自己更有效的資料傳輸機制。
Transfer-Encoding: chunked
複製程式碼
Transfer-Encoding 也屬於 Hop-by-hop(逐跳) 首部
,下面來回顧一下,HTTP 報文標頭除了可以根據屬性所在的位置分為 通用標頭
、請求標頭
、響應標頭
和 實體標頭
;還可以按照是否被快取分為 端到端首部(End-to-End)
和 逐跳首部(Top-to-Top)
。
除了下面八種屬於逐跳首部外,其餘都屬於端到端首部
Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization、Trailer、TE、Transfer-Encoding、Upgrade
下面回到討論中來,Transfer-Encoding 用於兩個節點之間傳輸訊息,而不是資源本身。在多個節點傳輸訊息的過程中,每一段訊息的傳輸都可以使用不同的 Transfer-Encoding
。如圖所示
Transfer-Encoding 支援檔案壓縮,如果你想要以檔案壓縮後的形式傳送的話。Transfer-Encoding 所有可選型別如下
chunked
: 資料按照一系列塊傳送,在這種情況下,將省略Content-Length
標頭,並在每個塊的開頭,需要以十六進位制填充當前塊的長度,後跟'\r\n'
,然後是塊本身,然後是另一個'\r\n'
。當將大量資料傳送到客戶端並且在請求已被完全處理之前,可能無法知道響應的總大小時,分塊編碼很有用。 例如,在生成由資料庫查詢產生的大型 HTML 表時或在傳輸大型影像時。 分塊的響應看起來像這樣
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
\r\n
複製程式碼
終止塊通常是0。緊隨Transfer-Encoding
後面的是 Trailer
標頭, Trailer 可能為空。
compress
: 使用Lempel-Ziv-Welch(LZW)
演算法的格式。值名稱取自UNIX
壓縮程式,該程式實現了該演算法。現在幾乎沒有瀏覽器使用這種內容編碼了,因為這個專利在 2003 年就停掉了。deflate
:使用zlib(在 RFC 1950 定義)
結構和 deflate 壓縮演算法gzip
: 使用Lempel-Ziv編碼(LZ77)
和32位CRC
的格式。這最初是UNIX gzip
程式的格式。HTTP / 1.1
標準還建議出於相容性目的,支援此內容編碼的伺服器應將 x-gzip 識別為別名。identity
: 使用身份功能(即無壓縮或修改)。
也可以列出多個值,以逗號分隔,類似一個集合列表
Transfer-Encoding: gzip, chunked
複製程式碼
Upgrade
首部欄位 Upgrade 用於檢測 HTTP 協議及其他協議是否可使用更高的版本進行通訊,其引數值可以用來指定一個完全不同的通訊協議。
上圖用例中,首部欄位 Upgrade
指定的值為 TLS/1.0
。請注意此處兩個欄位首部欄位的對應關係,Connection 的值被指定為 Upgrade。
Upgrade 首部欄位產生作用的物件僅限於客戶端和臨近伺服器之間。因此,使用首部欄位 Upgrade 時,還需要額外指定 Connection: Upgrade
。
對於附有首部欄位 Upgrade 的請求,伺服器可用 101 Switching Protocols
狀態碼作為響應返回。
Via
使用 Via 是為了跟蹤客戶端和伺服器之間的請求/響應路徑,避免請求迴圈以及能夠識別請求/響應
鏈中傳送者協議的功能。Via 欄位由代理伺服器新增,不論是正向代理還是反向代理,並且可以出現在請求標頭和響應標頭中。它用於跟蹤訊息轉發。例如下圖所示
Via 後面的的 1.1, 1.0
表示接收伺服器上的 HTTP 版本,Via 首部是為了跟蹤路徑,經常和 TRACE
方法一起使用。
Warning
注意:Warning 欄位即將被棄用
查閱 Warning (https://github.com/httpwg/http-core/issues/139) and Warning: header & stale-while-revalidate (https://github.com/whatwg/fetch/issues/913) 獲取更多細節
Warning 通用 HTTP 標頭通常會告知使用者一些與快取相關的問題的警告
HTTP/1.1 中定義了 7 種警告。它們分別如下
請求標頭
請求標頭用於客戶端傳送 HTTP 請求到伺服器中所使用的欄位,下面我們一起來看一下 HTTP 請求標頭都包含哪些欄位,分別是什麼意思。下面會介紹
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Authorization
- Expect
- From
- Host
- If-Match
- If-Modified-Since
- If-None-Match
- If-Range
- If-Unmodified-Since
- Max-Forwards
- Proxy-Authorization
- RangeReferer
- TE
- User-Agent
下面分別來介紹一下
Accept
HTTP 請求標頭會告知客戶端能夠接收的 MIME 型別是什麼
那麼什麼是 MIME 型別呢?在回答這個問題前你應該先了解一下什麼是 MIME
MIME: MIME (Multipurpose Internet Mail Extensions) 是描述訊息內容型別的因特網標準。MIME 訊息能包含文字、影像、音訊、視訊以及其他應用程式專用的資料。
也就是說,MIME 型別其實就是一系列訊息內容型別的集合。那麼 MIME 型別都有哪些呢?
文字檔案
: text/html、text/plain、text/css、application/xhtml+xml、application/xml
圖片檔案
: image/jpeg、image/gif、image/png
視訊檔案
: video/mpeg、video/quicktime
應用程式二進位制檔案
: application/octet-stream、application/zip
比如,如果瀏覽器不支援 PNG 圖片的顯示,那 Accept 就不指定image/png,而指定可處理的 image/gif 和 image/jpeg 等圖片型別。
一般 MIME 型別也會和 q
這個屬性一起使用,q 是什麼?q 表示的是權重,來看一個例子
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
複製程式碼
這是什麼意思呢?若想要給顯示的媒體型別增加優先順序,則使用 q= 來額外表示權重值,沒有顯示權重的時候預設值是1.0 ,我給你列個表格你就明白了
q | MIME |
---|---|
1.0 | text/html |
1.0 | application/xhtml+xml |
0.9 | application/xml |
0.8 | * / * |
也就是說,這是一個放置順序,權重高的在前,低的在後,application/xml;q=0.9
是不可分割的整體。
Accept-Charset
Accept-Charset
表示客戶端能夠接受的字元編碼。Accept-Charset 也是屬於內容協商
的一部分,它和
Accept
一樣,也可以用 q 來表示字符集,用逗號
進行分割,例如
Accept-Charset: iso-8859-1
Accept-Charset: utf-8, iso-8859-1;q=0.5
Accept-Charset: utf-8, iso-8859-1;q=0.5, *;q=0.1
複製程式碼
事實上,很多以
Accept-*
開頭的標頭,都是屬於內容協商的範疇,關於內容協商我們下面會說。
Accept-Encoding
表示 HTTP 標頭會標明客戶端希望服務端返回的內容編碼,這通常是一種壓縮演算法。Accept-Encoding 也是屬於內容協商
的一部分,使用並通過客戶端選擇 Content-Encoding
內容進行返回。
即使客戶端和伺服器都能夠支援相同的壓縮演算法,伺服器也可能選擇不壓縮並返回,這種情況可能是由於這兩種情況造成的:
- 要傳送的資料已經被壓縮了一次,第二次壓縮並不會導致傳送的資料更小
- 伺服器過載,無法承受壓縮帶來的效能開銷,通常,如果伺服器使用 CPU 超過 80% ,
Microsoft
則建議不要使用壓縮
下面是 Accept-Encoding 的使用方式
Accept-Encoding: gzip
Accept-Encoding: compress
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5
複製程式碼
上面的幾種表述方式就已經把 Accept-Encoding 的屬性列全了
-
gzip
: 由檔案壓縮程式 gzip 生成的編碼格式,使用Lempel-Ziv編碼(LZ77)
和32位CRC的壓縮格式,感興趣的同學可以讀一下 (en.wikipedia.org/wiki/LZ77_a… -
compress
: 使用Lempel-Ziv-Welch(LZW)
演算法的壓縮格式,有興趣的同學可以讀 (en.wikipedia.org/wiki/LZW) -
deflate
: 使用 zlib 結構和 deflate 壓縮演算法的壓縮格式,參考 (en.wikipedia.org/wiki/Zlib) 和 (en.wikipedia.org/wiki/DEFLAT… -
br
: 使用 Brotli 演算法的壓縮格式,參考 (en.wikipedia.org/wiki/Brotli… -
不執行壓縮或不會變化的預設編碼格式
-
*
: 匹配標頭中未列出的任何內容編碼,如果沒有列出Accept-Encoding
,這就是預設值,並不意味著支持任何演算法,只是表示沒有偏好
-
;q=
採用權重 q 值來表示相對優先順序,這點與首部欄位 Accept 相同。
Accept-Language
Accept-Language
請求表示客戶端需要服務端返回的語言型別,Accept-Language 也屬於內容協商的範疇。服務端通過 Content-Language
進行響應,和 Accept 首部欄位一樣,按權重值 q
來表示相對優先順序。例如
Accept-Language: de
Accept-Language: de-CH
Accept-Language: en-US,en;q=0.5
複製程式碼
Authorization
HTTP Authorization
請求頭用於向伺服器認證使用者代理的憑據,通常用在伺服器以401未經授權狀態和WWW-Authenticate標頭響應之後,啥意思呢?你不明白的話我畫張圖給你看
請求標頭 Authorization
是用來告知伺服器,使用者的認證資訊,伺服器在只有收到認證後才會返回給客戶端 200 OK 的響應,如果沒有認證資訊,則會返回 401 並告知客戶端需要認證資訊。詳細關於 Authorization 的資訊,後面也會詳細解釋
Expect
Expect HTTP 請求標頭指示伺服器需要滿足的期望才能正確處理請求。如果伺服器沒有辦法完成客服端所期望完成的事情並且服務端存在錯誤的話,會返回 417 Expectation Failed
。HTTP 1.1 只規定了100-continue
。
- 如果伺服器能正常完成客戶端所期望的事情,會返回 100
- 如果不能滿足期望或返回任何其他
4xx
的狀態碼,會返回 417
例如
PUT /somewhere/fun HTTP/1.1
Host: origin.example.com
Content-Type: video/h264
Content-Length: 1234567890987
Expect: 100-continue
複製程式碼
From
From
請求頭用來告知伺服器使用使用者代理的電子郵件地址。通常情況下,其使用目的就是為了顯示搜尋引擎等使用者代理的負責人的電子郵件聯絡方式。我們在使用代理的情況下,應儘可能包含 From 首部欄位。例如
From: webmaster@example.org
複製程式碼
你不應該將 From 用在訪問控制或者身份驗證中
Host
Host
請求頭指明瞭伺服器的域名(對於虛擬主機來說),以及(可選的)伺服器監聽的TCP埠號。如果沒有給定埠號,會自動使用被請求服務的預設埠(比如請求一個 HTTP 的 URL 會自動使用80作為埠)。
Host: developer.mozilla.org
複製程式碼
Host 首部欄位在 HTTP/1.1 規範內是唯一一個必須被包含在請求內的首部欄位。
If-Match
If-Match 後面可以跟一大堆屬性,形式像 If-Match 這種的請求頭稱為條件請求
,伺服器接收到條件請求後,需要判定條件請求是否滿足,只有條件請求為真,才會執行條件請求
類似的還有 If-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since
對於 GET
和 POST
方法,伺服器僅在與列出的 ETag(響應標頭)
之一匹配時才返回請求的資源。這裡又多了一個新詞 ETag
,我們稍後再說 ETag 的用法。對於像是 PUT
和其他非安全的方法,在這種情況下,它僅僅將上傳資源。
下面是兩種常見的案例
- 對於
GET
和POST
方法,會結合使用Range
標頭,它可以確保新傳送請求的範圍與上一個請求的資源相同,如果不匹配的話,會返回416
響應。 - 對於其他方法,特別是
PUT
方法,If-Match
可以防止丟失更新,伺服器會比對 If-Match 的欄位值和資源的 ETag 值,僅當兩者一致時,才會執行請求。反之,則返回狀態碼 412 Precondition Failed 的響應。例如
If-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"
If-Match: *
複製程式碼
If-Modified-Since
If-Modified-Since
是 HTTP 條件請求的一部分,只有在給定日期之後,服務端修改了請求所需要的資源,才會返回 200 OK 的響應。如果在給定日期之後,服務端沒有修改內容,響應會返回 304
並且不帶任何響應體。If-Modified-Since 只能使用 GET
和 HEAD
請求。
If-Modified-Since 與 If-None-Match 結合使用時,它將被忽略,除非伺服器不支援 If-None-Match。一般表示如下
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
複製程式碼
注意:這是格林威治標準時間。 HTTP 日期始終以格林尼治標準時間表示,而不是本地時間。
If-None-Match
條件請求,它與 If-Match
的作用相反,僅當 If-None-Match
的欄位值與 ETag
值不一致時,可處理該請求。對於GET
和 HEAD
,僅當伺服器沒有與給定資源匹配的 ETag
時,伺服器將返回 200 作為響應。對於其他方法,僅當最終現有資源的 ETag 與列出的任何值都不匹配時,才會處理請求。
當 GET
和 POST
傳送的 If-None-Match
與 ETag
匹配時,伺服器會返回 304
。
If-None-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"
If-None-Match: W/"67ab43", "54ed21", "7892dd"
If-None-Match: *
複製程式碼
有同學可能會好奇 W/
是什麼意思,這其實是 ETag 的弱匹配,關於 ETag 我們會在響應標頭中詳細講述。
If-Range
If-Range
也是條件請求,如果滿足條件(If-Range 的值和 ETag 值或者更新的日期時間一致),則會發出範圍請求,否則將會返回全部資源。它的一般表示如下
If-Range: Wed, 21 Oct 2015 07:28:00 GMT
複製程式碼
If-Unmodified-Since
If-Unmodified-Since
HTTP 請求標頭也是一個條件請求,伺服器只有在給定日期之後沒有對其進行修改時,伺服器才返回請求資源。如果在指定日期時間後發生了更新,則以狀態碼 412 Precondition Failed
作為響應返回。
If-Unmodified-Since: Wed, 21 Oct 2015 07:28:00 GMT
複製程式碼
Max-Forwards
MDN 把這個標頭置灰了,所以下面內容取自《圖解 HTTP》
Max-Forwards
一般用於 TRACE
和 OPTION
方法,傳送包含 Max-Forwards
的首部欄位時,每經過一個伺服器,Max-Forwards 的值就會 -1,直到 Max-Forwards 為0時返回。Max-Forwards 是一個十進位制的整數值。
Max-Forwards: 10
複製程式碼
可以靈活使用首部欄位 Max-Forwards,針對以上問題產生的原因展開調查。由於當 Max-Forwards 欄位值為 0 時,伺服器就會立即返回響應,由此我們至少可以對以那臺伺服器為終點的傳輸路徑的通訊狀況有所把握。
Proxy-Authorization
Proxy-Authorization
是屬於請求與認證的範疇,我們在上面提到一個認證的 HTTP 標頭是 Authorization,不同於 Authorization 發生在客戶端 - 伺服器之間;Proxy-Authorization
發生在代理伺服器和客戶端之間。它表示接收到從代理伺服器發來的認證時,客戶端會傳送包含首部欄位 Proxy-Authorization 的請求,以告知伺服器認證所需要的資訊。
Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
複製程式碼
Range
Range
HTTP 請求標頭指示伺服器應返回文件指定部分的資源,可以一次請求一個 Range 來返回多個部分,伺服器會將這些資源返回各個文件中。如果伺服器成功返回,那麼將返回 206 響應;如果 Range 範圍無效,伺服器返回416 Range Not Satisfiable
錯誤;伺服器還可以忽略 Range 標頭,並且返回 200 作為響應。
Range: bytes=200-1000, 2000-6576, 19000-
複製程式碼
Referer
HTTP Referer 屬性是請求標頭的一部分,當瀏覽器向 web 伺服器傳送請求的時候,一般會帶上 Referer,告訴伺服器該網頁是從哪個頁面連結過來的,伺服器因此可以獲得一些資訊用於處理。
Referer: https://developer.mozilla.org/testpage.html
複製程式碼
TE
首部欄位 TE
會告知伺服器客戶端能夠處理響應的傳輸編碼方式及相對優先順序。它和首部欄位 Accept-Encoding 的功能很相像,但是用於傳輸編碼。
TE: gzip, deflate;q=0.5
複製程式碼
首部欄位 TE 除指定傳輸編碼之外,還可以指定伴隨 trailer 欄位的分塊傳輸編碼的方式。應用後者時,只需把 trailers 賦值給該欄位值。
TE: trailers, deflate;q=0.5
複製程式碼
User-Agent
首部欄位 User-Agent
會將建立請求的瀏覽器和使用者代理名稱等資訊傳達給伺服器。
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0
複製程式碼
響應標頭
剛剛我們的著重點一直放在客戶端請求,現在我們把關注點轉換一下放在伺服器上。響應首部欄位是由伺服器傳送給客戶端響應中所包含的欄位,用於補充相應資訊等,這部分標頭也是非常多,我們先一起來看一下
- Accept-Ranges
- Age
- ETag
- Location
- Proxy-Authenticate
- Retry-After
- Server
- Vary
- www-Authenticate
Accept-Ranges
Accept-Ranges HTTP 響應標頭,這個標頭有兩個值
- 當伺服器能夠處理客戶端傳送過來的請求時,使用
bytes
來指定 - 當伺服器不能處理客戶端發來的請求時,使用
none
來指定
Accept-Ranges: bytes
Accept-Ranges: none
複製程式碼
Age
Age HTTP 響應標頭告訴客戶端源伺服器在多久之前建立了響應,它的單位為秒
,Age 標頭通常接近於0,如果是0則可能是從源伺服器獲取的,如果不是表示可能是由代理伺服器建立,那麼 Age 的值表示的是快取後的響應再次發起認證到認證完成的時間值。代理建立響應時必須加上首部欄位 Age。一般表示如下
Age: 24
複製程式碼
ETag
ETag 對於條件請求來說真是太重要了。因為條件請求就是根據 ETag 的值進行匹配的,下面我們就來詳細瞭解一下。
ETag 響應頭是特定版本
的標識,它能夠使快取變得更高效並能夠節省頻寬,因為如果快取內容未發生變更,Web 伺服器則不需要重新傳送完整的響應。除此之外,ETag 能夠防止資源同時更新互相覆蓋。
如果給定 URL 上的資源發生變更,必須生成一個新的 ETag
值,通過比較它們可以確定資源的兩個表示形式是否相同。
ETag 值有兩種,一種是強 ETag,一種是弱 ETag;
- 強 ETag 值,無論實體發生多麼細微的變化都會改變其值,一般的表示如下
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
複製程式碼
- 弱 ETag 值,弱 ETag 值只用於提示資源是否相同。只有資源發生了根本改變,產生差異時才會改變 ETag 值。這時,會在欄位值最開始處附加 W/。
ETag: W/"0815"
複製程式碼
Location
Location 響應標頭表示 URL 需要重定向頁面,它僅僅與 3xx(重定向)
或 201(已建立)
狀態響應一起使用。下面是一個頁面重定向的過程
使用首部欄位 Location 可以將響應接受方引導至某個與請求 URI 位置不同的資源。
Location
和 content-Location
是不一樣的:Location 表示目標的重定向(或新建立資源的 URL)。然而 Content-Location 表示發生內容協商時用於訪問資源的直接 URL,而無須進一步協商。Location 是與響應相關聯的標頭,而 Content-Location 與返回的實體相關聯。
Location: /index.html
複製程式碼
Proxy-Authenticate
HTTP 響應標頭 Proxy-Authenticate
會定義認證方法,應該使用身份驗證方法來訪問代理伺服器後面的資源即客戶端。
它與 HTTP 客戶端和服務端之間的訪問認證行為相似,不同之處在於 Proxy-Authenticate
的認證雙方是客戶端與代理之間。它的一般表示形式如下
Proxy-Authenticate: Basic
Proxy-Authenticate: Basic realm="Access to the internal site"
複製程式碼
Retry-After
HTTP 響應標頭 Retry-After 告知客戶端需要在多久之後重新傳送請求,使用此標頭主要有如下三種情況
- 當傳送
503(服務不可用)
響應時,這表示該服務預計無法使用多長時間。 - 當傳送
429(太多請求)
響應時,這表示發出新請求之前要等待多長時間。 - 當傳送重定向的響應像是
301(永久移動)
,這表示在發出重定向請求之前要求使用者客戶端等待的最短時間。
欄位值可以指定為具體的日期時間,也可以是建立響應後所持續的秒數,例如
Retry-After: Wed, 21 Oct 2015 07:28:00 GMT
Retry-After: 120
複製程式碼
Server
伺服器標頭包含有關原始伺服器用來處理請求的軟體的資訊。
應該避免使用過於冗長和詳細的 Server 值,因為它們可能會洩露內部實施細節,這可能會使攻擊者容易地發現並利用已知的安全漏洞。例如下面這種寫法
Server: Apache/2.4.1 (Unix)
複製程式碼
Vary
Vary HTTP 響應標頭確定如何匹配請求標頭,以決定是否可以使用快取的響應,而不是從原始伺服器請求一個新的響應。
Vary: User-Agent
複製程式碼
www-Authenticate
HTTP WWW-Authenticate
響應標頭定義了應用於獲得對資源的訪問許可權的身份驗證方法。WWW-Authenticate標頭與401未經授權的響應一起傳送。它的一般表示形式如下
WWW-Authenticate: Basic
WWW-Authenticate: Basic realm="Access to the staging site", charset="UTF-8"
複製程式碼
Access-Control-Allow-Origin
一個返回的 HTTP 標頭可能會具有 Access-Control-Allow-Origin ,Access-Control-Allow-Origin
指定一個來源,它告訴瀏覽器允許該來源進行資源訪問。 否則-對於沒有憑據的請求 *
萬用字元,告訴瀏覽器允許任何源訪問資源。例如,要允許源 https://mozilla.org
的程式碼訪問資源,可以指定:
Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin
複製程式碼
如果伺服器指定單個來源而不是 *
萬用字元的話 ,則伺服器還應在 Vary 響應標頭中包含 Origin
,以向客戶端指示 伺服器響應將根據原始請求標頭的值而有所不同。
實體標頭
實體標頭用於HTTP請求和響應中,例如 Content-Length,Content-Language,Content-Encoding 的標頭是實體標頭。實體標頭不侷限於請求標頭或者響應標頭,下面例子中,Content-Length
是一個實體標頭,但是卻出現在了請求報文中
POST /myform.html HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Content-Length: 128
複製程式碼
下面就來說一下實體標頭都包含哪些
- Allow
- Content-Encoding
- Content-Language
- Content-Length
- Content-Location
- Content-MD5
- Content-Range
- Content-Type
- Expires
- Last-Modified
下面來分開說一下
Allow
HTTP 實體標頭 Allow
列出了資源支援的方法集合。如果伺服器響應405 Method Not Allowed
狀態碼以指示可以使用哪些請求方法,則必須傳送此標頭。例如
Allow: GET, POST, HEAD
複製程式碼
這段程式碼表示伺服器允許支援 GET
、POST
和 HEAD
方法。當伺服器接收到不支援的 HTTP 方法時,會以狀態碼 405 Method Not Allowed
作為響應返回。
Content-Encoding
我們上面講過 Accept-Encoding
是客戶端希望服務端返回的內容編碼,但是實際上服務端返回給客戶端的內容編碼實際上是通過 Content-Encoding
返回的。內容編碼是指在不丟失實體資訊的前提下所進行的壓縮。主要也是四種,和 Accept-Encoding 相同,它們是 gzip、compress、deflate、identity。下面是一組請求/響應內容壓縮編碼
Accept-Encoding: gzip, deflate
Content-Encoding: gzip
複製程式碼
Content-Language
首部欄位 Content-Language 會告知客戶端,伺服器使用的自然語言是什麼,它與 Accept-Language 相對,下面是一組請求/響應使用的語言型別
Content-Language: de-DE, en-CA
複製程式碼
Content-Length
Content-Length 的實體標頭指伺服器傳送給客戶端的實際主體大小,以位元組為單位。
Content-Length: 3000
複製程式碼
如上,伺服器返回給客戶端的主體大小是 3000 位元組。
Content-Location
Content-Location 可不是對應 Accept-Location,因為沒有這個標頭哈哈哈哈。實際上 Content-Location 對應的是 Location
。
Location 和 Content-Location 是不一樣的,Location 表示重定向的 URL,而 Content-Location 表示用於訪問資源的直接 URL,以後無需進行進一步的內容協商。Location 是與響應關聯的標頭,而 Content-Location 是與返回的資料相關聯的標頭,如果你不好理解,看一下下面的表格
Request header | Response header |
---|---|
Accept: application/json, text/json |
Content-Location: /documents/foo.json |
Accept: application/xml, text/xml |
Content-Location: /documents/foo.xml |
Accept: text/plain, text/* |
Content-Location: /documents/foo.txt |
Content-MD5
客戶端會對接收的報文主體執行相同的 MD5 演算法,然後與首部欄位 Content-MD5 的欄位進行比較。
Content-MD5: e10adc3949ba59abbe56e057f20f883e
複製程式碼
首部欄位 Content-MD5 是一串由 MD5 演算法生成的值,其目的在於檢查報文主體在傳輸過程中是否保持完整,有無被修改的情況,以及確認傳輸到達。
Content-Range
HTTP 的 Content-Range 響應標頭是針對範圍請求而設定的,返回響應時使用首部欄位 Content-Range
,能夠告知客戶端響應實體的哪部分是符合客戶端請求的,欄位以位元組為單位。它的一般表示如下
Content-Range: bytes 200-1000/67589
複製程式碼
上段程式碼表示從所有 67589
個位元組中返回 200-1000
個位元組的內容
Content-Type
HTTP 響應標頭 Content-Type 說明了實體內物件的媒體型別,和首部欄位 Accept 一樣使用,表示伺服器能夠響應的媒體型別。
Expires
HTTP Expires 實體標頭包含 日期/時間
,在該日期/時間之後,響應被認為過期;在響應時間之內被認為有效。特殊的值比如0表示過去的日期,表示資源已過期。
Expires: Wed, 21 Oct 2015 07:28:00 GMT
複製程式碼
源伺服器會將資源失效的日期或時間傳送給客戶端,快取伺服器在接受到 Expires 的響應後,會判斷是否把快取返回給客戶端。
源伺服器不希望快取伺服器對資源快取時,最好在 Expires 欄位內寫入與首部欄位 Date 相同的時間值。但是,當首部欄位 Cache-Control 有指定 max-age 指令時,比起首部欄位 Expires,會優先處理 max-age 指令。
Last-Modified
實體欄位 Last-Modified
指明資源的最後修改時間,它用作驗證器來確定接收或儲存的資源是否相同。它的作用不如 ETag
那麼準確,它可以作為一種後備機制,包含 If-Modified-Since
或 If-Unmodified-Since
標頭的條件請求將使用此欄位。它的一般表示如下
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
複製程式碼
總結
本篇文章主要介紹了 HTTP 四種標頭的基本概念,但是並沒有涵蓋全部,畢竟 HTTP 標頭內容確實太多了,以上介紹的基本都是平常工作中常用的一些概念,下一篇文章預告 HTTP 的黑科技
文章參考:
developer.mozilla.org/en-US/docs/…
www.tcpipguide.com/free/t_HTTP…
www.tcpipguide.com/free/t_HTTP…
developer.mozilla.org/en-US/docs/…
《圖解 HTTP》