HTTP報文首部
HTTP協議的請求和響應報文中必定包含HTTP首部。首部内容為客戶端和服務器分别處理請求和響應提供所需要的信息。對于客戶端用戶來說,這些信息中的大部分内容都無須親自查看。
報文首部由幾個字段構成。
下面的示例是訪問http://hackr.jp時,請求報文的首部信息。
HTTP響應報文
在響應中,HTTP報文由HTTP版本、狀态碼(數字和原因短語)、HTTP首部字段3部分構成。
以下示例是之前請求訪問http://hackr.jp/時,返回的響應報文的首部信息。
在報文衆多的字段當中,HTTP首部字段包含的信息最為豐富。首部字段同時存在于請求和響應報文内,并涵蓋HTTP報文相關的内容信息。
因HTTP版本或擴展規範的變化,首部字段可支持的字段内容略有不同。本書主要涉及HTTP/1.1及常用的首部字段。
HTTP首部字段
HTTP首部字段傳遞重要信息
HTTP首部字段是構成HTTP報文的要素之一。在客戶端與服務器之間以HTTP協議進行通信的過程中,無論是請求還是響應都會使用首部字段,它能起到傳遞額外重要信息的作用。
使用首部字段是為了給浏覽器和服務器提供報文主體大小、所使用的語言、認證信息等内容。
HTTP首部字段結構
HTTP首部字段是由首部字段名和字段值構成的,中間用冒号“:”分隔。
例如,在HTTP首部中以Content-Type這個字段來表示報文主體的對象類型。
就以上述示例來看,首部字段名為Content-Type,字符串text/html是字段值。
另外,字段值對應單個HTTP首部字段可以有多個值
4種HTTP首部字段類型
HTTP首部字段根據實際用途被分為以下4種類型。
HTTP/1.1 首部字段一覽
HTTP/1.1規範定義了如下47種首部字段。
非HTTP/1.1首部字段
在HTTP協議通信交互中使用到的首部字段,不限于RFC2616中定義的47種首部字段。還有Cookie、Set-Cookie和Content-Disposition等在其他RFC中定義的首部字段,它們的使用頻率也很高。
這些非正式的首部字段統一歸納在RFC4229 HTTP Header Field Registrations中。
End-to-end首部和Hop-by-hop首部
HTTP首部字段将定義成緩存代理和非緩存代理的行為,分成2種類型。
下面列舉了HTTP/1.1中的逐跳首部字段。除這8個首部字段之外,其他所有字段都屬于端到端首部。
HTTP/1.1 通用首部字段
通用首部字段是指,請求報文和響應報文雙方都會使用的首部。
Cache-Control
通過指定首部字段Cache-Control的指令,就能操作緩存的工作機制。
指令的參數是可選的,多個指令之間通過“,”分隔。首部字段Cache-Control的指令可用于請求及響應時。
Cache-Control指令一覽
表示是否能緩存的指令
public指令
當指定使用public指令時,則明确表明其他用戶也可利用緩存。
private指令
當指定private指令後,響應隻以特定的用戶作為對象,這與public指令的行為相反。
緩存服務器會對該特定用戶提供資源緩存的服務,對于其他用戶發送過來的請求,代理服務器則不會返回緩存。
no-cache指令
使用no-cache指令的目的是為了防止從緩存中返回過期的資源。
客戶端發送的請求中如果包含no-cache指令,則表示客戶端将不會接收緩存過的響應。于是,“中間”的緩存服務器必須把客戶端請求轉發給源服務器。
如果服務器返回的響應中包含no-cache指令,那麼緩存服務器不能對資源進行緩存。源服務器以後也将不再對緩存服務器請求中提出的資源有效性進行确認,且禁止其對相應資源進行緩存操作。
由服務器返回的響應中,若報文首部字段cache-Control中對no-cache字段名具體指定參數值,那麼客戶端在接收到這個被指定參數值的首部字段對應的響應報文後,就不能使用緩存。換言之,無參數值的首部字段可以使用緩存。隻能在響應指令中指定該參數。
控制可執行緩存的對象的指令
no-store指令
當使用no-store指令[插圖]時,暗示請求(和對應的響應)或響應中包含機密信息。
因此,該指令規定緩存不能在本地存儲請求或響應的任一部分。
指定緩存期限和認證的指令
s-maxage指令
s-maxage指令的功能和max-age指令的相同,它們的不同點是s-maxage指令隻适用于供多位用戶使用的公共緩存服務器[插圖]。也就是說,對于向同一用戶重複返回響應的服務器來說,這個指令沒有任何作用。
另外,當使用s-maxage指令後,則直接忽略對Expires首部字段及max-age指令的處理。
max-age指令
當客戶端發送的請求中包含max-age指令時,如果判定緩存資源的緩存時間數值比指定時間的數值更小,那麼客戶端就接收緩存的資源。另外,當指定max-age值為0,那麼緩存服務器通常需要将請求轉發給源服務器。
當服務器返回的響應中包含max-age指令時,緩存服務器将不對資源的有效性再作确認,而max-age數值代表資源保存為緩存的最長時間。
應用HTTP/1.1版本的緩存服務器遇到同時存在Expires首部字段的情況時,會優先處理max-age指令,而忽略掉Expires首部字段。而HTTP/1.0版本的緩存服務器的情況卻相反,max-age指令會被忽略掉。
min-fresh指令
min-fresh指令要求緩存服務器返回至少還未過指定時間的緩存資源。
比如,當指定min-fresh為60秒後,在這60秒以内如果有超過有效期限的資源都無法作為響應返回了。
max-stale指令
使用max-stale可指示緩存資源,即使過期也照常接收。
如果指令未指定參數值,那麼無論經過多久,客戶端都會接收響應;如果指令中指定了具體數值,那麼即使過期,隻要仍處于max-stale指定的時間内,仍舊會被客戶端接收。
only-if-cached指令
使用only-if-cached指令表示客戶端僅在緩存服務器本地緩存目标資源的情況下才會要求其返回。換言之,該指令要求緩存服務器不重新加載響應,也不會再次确認資源有效性。若發生請求緩存服務器的本地緩存無響應,則返回狀态碼504 GatewayTimeout。
must-revalidate指令
使用must-revalidate指令,代理會向源服務器再次驗證即将返回的響應緩存目前是否仍然有效。
若代理無法連通源服務器再次獲取有效資源的話,緩存必須給客戶端一條504(Gateway Timeout)狀态碼。
另外,使用must-revalidate指令會忽略請求的max-stale指令(即使已經在首部使用了max-stale,也不會再有效果)。
proxy-revalidate指令
proxy-revalidate指令要求所有的緩存服務器在接收到客戶端帶有該指令的請求返回響應之前,必須再次驗證緩存的有效性。
no-transform指令
使用no-transform指令規定無論是在請求還是響應中,緩存都不能改變實體主體的媒體類型。
這樣做可防止緩存或代理壓縮圖片等類似操作。
Cache-Control擴展
cache-extension token
通過Cache-extension标記(token),可以擴展Cache-Control首部字段内的指令。
如上例,Cache-Control首部字段本身沒有community這個指令。借助extension tokens實現了該指令的添加。如果緩存服務器不能理解community這個新指令,就會直接忽略。因此,extension tokens僅對能理解它的緩存服務器來說是有意義的。
Connection
Connection首部字段具備如下兩個作用。
在客戶端發送請求和服務器返回響應内,使用Connection首部字段,可控制不再轉發給代理的首部字段(即Hop-by-hop首部)。
管理持久連接
HTTP/1.1版本的默認連接都是持久連接。為此,客戶端會在持久連接上連續發送請求。當服務器端想明确斷開連接時,則指定Connection首部字段的值為Close。
HTTP/1.1之前的HTTP版本的默認連接都是非持久連接。為此,如果想在舊版本的HTTP協議上維持持續連接,則需要指定Connection首部字段的值為Keep-Alive。
Date
首部字段Date表明創建HTTP報文的日期和時間。
HTTP/1.1協議使用在RFC1123中規定的日期時間的格式
之前的HTTP協議版本中使用在RFC850中定義的格式
除此之外,還有一種格式。它與C标準庫内的asctime()函數的輸出格式一緻。
Pragma
Pragma是HTTP/1.1之前版本的曆史遺留字段,僅作為與HTTP/1.0的向後兼容而定義。
規範定義的形式唯一
該首部字段屬于通用首部字段,但隻用在客戶端發送的請求中。客戶端會要求所有的中間服務器不返回緩存的資源。
所有的中間服務器如果都能以HTTP/1.1為基準,那直接采用Cache-Control: no-cache指定緩存的處理方式是最為理想的。但要整體掌握全部中間服務器使用的HTTP協議版本卻是不現實的。因此,發送的請求會同時含有下面兩個首部字段。
Trailer
首部字段Trailer會事先說明在報文主體後記錄了哪些首部字段。該首部字段可應用在HTTP/1.1版本分塊傳輸編碼時。
以上用例中,指定首部字段Trailer的值為Expires,在報文主體之後(分塊長度0之後)出現了首部字段Expires。
Transfer-Encoding
首部字段Transfer-Encoding規定了傳輸報文主體時采用的編碼方式。
HTTP/1.1的傳輸編碼方式僅對分塊傳輸編碼有效。
以上用例中,正如在首部字段Transfer-Encoding中指定的那樣,有效使用分塊傳輸編碼,且分别被分成3312字節和914字節大小的分塊數據。
Upgrade
首部字段Upgrade用于檢測HTTP協議及其他協議是否可使用更高的版本進行通信,其參數值可以用來指定一個完全不同的通信協議。
上圖用例中,首部字段Upgrade指定的值為TLS/1.0。請注意此處兩個字段首部字段的對應關系,Connection的值被指定為Upgrade。Upgrade首部字段産生作用的Upgrade對象僅限于客戶端和鄰接服務器之間。因此,使用首部字段Upgrade時,還需要額外指定Connection:Upgrade。
對于附有首部字段Upgrade的請求,服務器可用101 SwitchingProtocols狀态碼作為響應返回。
Via
使用首部字段Via是為了追蹤客戶端與服務器之間的請求和響應報文的傳輸路徑。
報文經過代理或網關時,會先在首部字段Via中附加該服務器的信息,然後再進行轉發。這個做法和traceroute及電子郵件的Received首部的工作機制很類似。
首部字段Via不僅用于追蹤報文的轉發,還可避免請求回環的發生。所以必須在經過代理時附加該首部字段内容。
在經過代理服務器A時,Via首部附加了“1.0 gw.hackr.jp (Squid/3.1)”這樣的字符串值。行頭的1.0是指接收請求的服務器上應用的HTTP協議版本。接下來經過代理服務器B時亦是如此,在Via首部附加服務器信息,也可增加1個新的Via首部寫入服務器信息。
Via首部是為了追蹤傳輸路徑,所以經常會和TRACE方法一起使用。比如,代理服務器接收到由TRACE方法發送過來的請求(其中Max-Forwards: 0)時,代理服務器就不能再轉發該請求了。這種情況下,代理服務器會将自身的信息附加到Via首部後,返回該請求的響應。
Warning
HTTP/1.1的Warning首部是從HTTP/1.0的響應首部(Retry-After)演變過來的。該首部通常會告知用戶一些與緩存相關的問題的警告。
Warning首部的格式如下。最後的日期時間部分可省略。
HTTP/1.1中定義了7種警告。警告碼對應的警告内容僅推薦參考。另外,警告碼具備擴展性,今後有可能追加新的警告碼。
,
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!