Http協議基礎之HTTP通用首部字段

通用首部字段

通用首部字段是指,請求報文和響應報文雙方都會使用的首部。

Cache-Control

通過指定首部字段 Cache-Control 的指令,就能操作緩存的工作機制。
指令的參數是可選的,多個指令之間通過“,”分隔。首部字段 Cache-Control 的指令可用於請求及響應時。

Cache-Control: private, max-age=0, no-cache

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)

    表示是否能緩存的指令

  • public 指令
  • Cache-Control: public

    當指定使用 public 指令時,則明確表明其他用戶也可利用緩存。

  • private 指令
  • Cache-Control: private

    當指定 private 指令後,響應只以特定的用戶作爲對象,這與 public 指令的行爲相反。
    緩存服務器會對該特定用戶提供資源緩存的服務,對於其他用戶發送過來的請求,代理服務器則不會返回緩存。

  • no-cache 指令
  • Cache-Control: no-cache

    使用 no-cache 指令的目的是爲了防止從緩存中返回過期的資源。

    客戶端發送的請求中如果包含 no-cache 指令,則表示客戶端將不會接收緩存過的響應。於是,“中間”的緩存服務器必須把客戶端請求轉發給源服務器。

    如果服務器返回的響應中包含 no-cache 指令,那麼緩存服務器不能對資源進行緩存。源服務器以後也將不再對緩存服務器請求中提出的資源有效性進行確認,且禁止其對響應資源進行緩存操作。

    Cache-Control: no-cache=Location

    由服務器返回的響應中,若報文首部字段 Cache-Control 中對 no-cache 字段名具體指定參數值,那麼客戶端在接收到這個被指定參數值的首部字段對應的響應報文後,就不能使用緩存。換言之,無參數值的首部字段可以使用緩存。只能在響應指令中指定該參數。

    控制可執行緩存的對象的指令

  • no-store 指令
  • Cache-Control: no-store

    當使用 no-store 指令時,暗示請求(和對應的響應)或響應中包含機密信息。因此,該指令規定緩存不能在本地存儲請求或響應的任一部分。

    注意:從字面意思上很容易把 no-cache 誤解成爲不緩存,但事實上 no-cache 代表不緩存過期的資源,緩存會向源服務器進行有效期確認後處理資源,也許稱爲 do-not-serve-from-cache-without-revalidation 更合適。no-store 纔是真正地不進行緩存。

    指定緩存期限和認證的指令

  • s-maxage 指令
  • Cache-Control: s-maxage=604800(單位 :秒)

    s-maxage 指令的功能和 max-age 指令的相同,它們的不同點是 s-maxage 指令只適用於供多位用戶使用的公共緩存服務器 (代理)。也就是說,對於向同一用戶重複返回響應的服務器來說,這個指令沒有任何作用。另外,當使用 s-maxage 指令後,則直接忽略對 Expires 首部字段及 max-age 指令的處理。

  • max-age 指令
  • Cache-Control: max-age=604800(單位:秒)

    當客戶端發送的請求中包含 max-age 指令時,如果判定緩存資源的緩存時間數值比指定時間的數值更小,那麼客戶端就接收緩存的資源。另外,當指定 max-age 值爲 0,那麼緩存服務器通常需要將請求轉發給源服務器。

    當服務器返回的響應中包含 max-age 指令時,緩存服務器將不對資源的有效性再作確認,而 max-age 數值代表資源保存爲緩存的最長時間。

    應用 HTTP/1.1 版本的緩存服務器遇到同時存在 Expires 首部字段的情況時,會優先處理 max-age 指令,而忽略掉 Expires 首部字段。而 HTTP/1.0 版本的緩存服務器的情況卻相反,max-age 指令會被忽略掉。

  • min-fresh 指令
  • Cache-Control: min-fresh=60(單位:秒)

    min-fresh 指令要求緩存服務器返回至少還未過指定時間的緩存資源。
    比如,當指定 min-fresh 爲 60 秒後,過了 60 秒的資源都無法作爲響應返回了。

  • max-stale 指令
  • Cache-Control: max-stale=3600(單位:秒)

    使用 max-stale 可指示緩存資源,即使過期也照常接收。

    如果指令未指定參數值,那麼無論經過多久,客戶端都會接收響應;如果指令中指定了具體數值,那麼即使過期,只要仍處於 max-stale 指定的時間內,仍舊會被客戶端接收。

  • only-if-cached 指令
  • Cache-Control: only-if-cached

    使用 only-if-cached 指令表示客戶端僅在緩存服務器本地緩存目標資源的情況下才會要求其返回。換言之,該指令要求緩存服務器不重新加載響應,也不會再次確認資源有效性。若發生請求緩存服務器的本地緩存無響應,則返回狀態碼 504 Gateway Timeout。

  • must-revalidate 指令
  • Cache-Control: must-revalidate

    使用 must-revalidate 指令,代理會向源服務器再次驗證即將返回的響應緩存目前是否仍然有效。
    若代理無法連通源服務器再次獲取有效資源的話,緩存必須給客戶端一條 504(Gateway Timeout)狀態碼。
    另外,使用 must-revalidate 指令會忽略請求的 max-stale 指令(即使已經在首部使用了 max-stale,也不會再有效果)。

  • proxy-revalidate 指令
  • Cache-Control: proxy-revalidate

    proxy-revalidate 指令要求所有的緩存服務器在接收到客戶端帶有該指令的請求返回響應之前,必須再次驗證緩存的有效性。

  • no-transform 指令
  • Cache-Control: no-transform

    使用 no-transform 指令規定無論是在請求還是響應中,緩存都不能改變實體主體的媒體類型。
    這樣做可防止緩存或代理壓縮圖片等類似操作。

    Cache-Control 擴展

  • cache-extension token
  • Cache-Control: private, community=”UCI”

    通過 cache-extension 標記(token),可以擴展 Cache-Control 首部字段內的指令。

    如上例,Cache-Control 首部字段本身沒有 community 這個指令。藉助 extension tokens 實現了該指令的添加。如果緩存服務器不能理解 community這個新指令,就會直接忽略。因此,extension tokens 僅對能理解它的緩存服務器來說是有意義的。

    Connection

    Connection 首部字段具備如下兩個作用。

  • 控制不再轉發給代理的首部字段
  • Connection: 不再轉發的首部字段名

    在客戶端發送請求和服務器返回響應內,使用 Connection 首部字段,可控制不再轉發給代理的首部字段(即 Hop-by-hop 首部)。

  • 管理持久連接
  • Connection: close

    HTTP/1.1 版本的默認連接都是持久連接。爲此,客戶端會在持久連接上連續發送請求。當服務器端想明確斷開連接時,則指定 Connection 首部字段的值爲 Close。

    Connection: Keep-Alive

    HTTP/1.1 之前的 HTTP 版本的默認連接都是非持久連接。爲此,如果想在舊版本的 HTTP 協議上維持持續連接,則需要指定 Connection 首部字段的值爲 Keep-Alive。

    Date

    首部字段 Date 表明創建 HTTP 報文的日期和時間。
    HTTP/1.1 協議使用在 RFC1123 中規定的日期時間的格式,如下 示例。

    Date: Tue, 03 Jul 2012 04:40:59 GMT

    之前的 HTTP 協議版本中使用在 RFC850 中定義的格式,如下所示。

    Date: Tue, 03-Jul-12 04:40:59 GMT

    除此之外,還有一種格式。它與 C 標準庫內的 asctime() 函數的輸出格式一致。

    Date: Tue Jul 03 04:40:59 2012

    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

    Trailer

    首部字段 Trailer 會事先說明在報文主體後記錄了哪些首部字段。該首部字段可應用在 HTTP/1.1 版本分塊傳輸編碼時。

    HTTP/1.1 200 OK
    Date: Tue, 03 Jul 2012 04:40:56 GMT
    Content-Type: text/html
    ...
    Transfer-Encoding: chunked
    Trailer: Expires
    
    ...(報文主體)...
    0
    Expires: Tue, 28 Sep 2004 23:59:59 GMT

    以上用例中,指定首部字段 Trailer 的值爲 Expires,在報文主體之後(分塊長度 0 之後)出現了首部字段 Expires。

  • Transfer-Encoding
    首部字段 Transfer-Encoding 規定了傳輸報文主體時採用的編碼方式。
  • HTTP/1.1 的傳輸編碼方式僅對分塊傳輸編碼有效。

    HTTP/1.1 200 OK
    Date: Tue, 03 Jul 2012 04:40:56 GMT
    Cache-Control: public, max-age=604800
    Content-Type: text/javascript; charset=utf-8
    Expires: Tue, 10 Jul 2012 04:40:56 GMT
    X-Frame-Options: DENY
    X-XSS-Protection: 1; mode=block
    Content-Encoding: gzip
    Transfer-Encoding: chunked
    Connection: keep-alive
    
    cf0    ←16進制(10進製爲3312)
    
    ...3312字節分塊數據...
    
    39216進制(10進製爲914)
    
    ...914字節分塊數據...
    
    0

    以上用例中,正如在首部字段 Transfer-Encoding 中指定的那樣,有效使用分塊傳輸編碼,且分別被分成 3312 字節和 914 字節大小的分塊數據。

    Upgrade

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

    客戶端發送請求:

    GET /index.htm HTTP/1.1
    Upgrade:TLS/1.0
    Connection:Upgrade

    服務器返回響應:

    HTTP/1.1 101 Switching Protocols
    Upgrade:TLS/1.0,HTTP/1.1
    Connection:Upgrade

    上例中,首部字段 Upgrade 指定的值爲 TLS/1.0。請注意此處兩個字段首部字段的對應關係,Connection 的值被指定爲 Upgrade。Upgrade 首部字段產生作用的 Upgrade 對象僅限於客戶端和鄰接服務器之間。因此,使用首部字段 Upgrade 時,還需要額外指定 Connection:Upgrade。

    對於附有首部字段 Upgrade 的請求,服務器可用 101 Switching Protocols 狀態碼作爲響應返回。

    Via

    使用首部字段 Via 是爲了追蹤客戶端與服務器之間的請求和響應報文的傳輸路徑。

    報文經過代理或網關時,會先在首部字段 Via 中附加該服務器的信息,然後再進行轉發。這個做法和 traceroute 及電子郵件的 Received 首部的工作機制很類似。

    首部字段 Via 不僅用於追蹤報文的轉發,還可避免請求迴環的發生。所以必須在經過代理時附加該首部字段內容。

    Via 首部是爲了追蹤傳輸路徑,所以經常會和 TRACE 方法一起使用。比如,代理服務器接收到由 TRACE 方法發送過來的請求(其中 Max-Forwards: 0)時,代理服務器就不能再轉發該請求了。這種情況下,代理服務器會將自身的信息附加到 Via 首部後,返回該請求的響應。

    Warning

    HTTP/1.1 的 Warning 首部是從 HTTP/1.0 的響應首部(Retry-After)演變過來的。該首部通常會告知用戶一些與緩存相關的問題的警告。

    Warning: 113 gw.hackr.jp:8080 “Heuristic expiration” Tue, 03 Jul 2012 05:09:44 GMT

    Warning 首部的格式如下。最後的日期時間部分可省略。

    Warning: [警告碼][警告的主機:端口號]“[警告內容]”([日期時間])

    HTTP/1.1 中定義了 7 種警告。警告碼對應的警告內容僅推薦參考。另外,警告碼具備擴展性,今後有可能追加新的警告碼。

    HTTP/1.1 警告碼

    警告碼 警告內容 說明
    110 Response is stale(響應已過期) 代理返回已過期的資源
    111 Revalidation failed(再驗證失敗) 代理再驗證資源有效性時失敗(服務器無法到達等原因)
    112 Disconnection operation(斷開連接操作) 代理與互聯網連接被故意切斷
    113 Heuristic expiration(試探性過期) 響應的使用期超過24小時(有效緩存的設定時間大於24小時的情況下)
    199 Miscellaneous warning(雜項警告) 任意的警告內容
    214 Transformation applied(使用了轉換) 代理對內容編碼或媒體類型等執行了某些處理時
    299 Miscellaneous persistent warning(持久雜項警告) Miscellaneous persistent warning(持久雜項警告)
    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章