REST筆記(五):你應該知道的HTTP頭------ETag


在HTTP1.1規范中,新增了一個HTTP頭信息:ETag。對Web開發者來說,它是一個非常重要的信息。它是用作緩存使

用的兩個主要的頭信息之一 (另一個是Expires)。除此之外,在REST架構中,它還可以用於控制並發操作(上節中已經大

致介紹AtomPub中控制並發的流程)。那么ETag是什么?它又幾種類型?強ETag與弱ETag之間有什么區別。?如何計算

ETag值?它與Last-Modified頭信息在使用上有什么區別?本節主要圍繞這幾個方面敘述一下自己的理解。


目錄:

  1. 什么是ETag?
  2. 計算ETag值
  3. ETag的類型以及他們之間的區別
  4. ETag與Last-Modified頭信息用途上的區別

什么是ETag? 

ETag:是實體標簽(Entity Tag)的縮寫。ETag一般不以明文形式相應給客戶端。在資源的各個生命周期中,它都具有不

值,用於標識出資源的狀態。當資源發生變更時,如果其頭信息中一個或者多個發生變化,或者消息實體發生變化

,那ETag也隨之發生化。

ETag值的變更說明資源狀態已經被修改。往往可以通過時間戳就可以便宜的得到ETag頭信息。在服務端中如果發回給

消費者的相應一開始起就由ETag控制,那么可以確保更細粒度的ETag升級完全由服務來進行控制。服務計算ETag值,

並在相應客戶端請求時將它返回給客戶端。

計算ETag值

在HTTP1.1協議中並沒有規范如何計算ETag。ETag值可以是唯一標識資源的任何東西,如持久化存儲中的某個資源關聯

的版本、一個或者多個文件屬性,實體頭信息和校驗值、(CheckSum),也可以計算實體信息的散列值。有時候,為了計

算一個ETag值可能有比較大的代價,此時可以采用生成唯一值等方式(如常見的GUID)。無論怎樣,服務都應該盡可能的

將ETag值返回給客戶端。客戶端不用關心ETag值如何產生,只要服務在資源狀態發生變更的情況下將ETag值發送給它就行

。下圖為MSDN中,OutgoingResponse類中設置ETag值的截圖:

2011-12-24_105957

從上圖可以看出,在REST架構下,ETag值可以通過Guid、整數、長整形、字符串四種類型的參數傳入SetETag方法,

WCF服務發回給客戶端的HTTP響應頭中就包含了ETag值。另外OutgoingResponse類也有字符串屬性:ETag直接給

它賦值也能在HTTP響應頭中寫入ETag值。

如下所示為使用文件屬性計算ETag:

 public class ETag : IHeader
    {
        private string Value;

        public ETag(string value)
        {
            Value = value;
            WebOperationContext.Current.OutgoingResponse.ETag
        }

        #region IHeader 成員

        public void AddHTTPHeader(ResponseContext context)
        {
            context.WriteHttpHeader(Value);
        }

        #endregion
    }
獲取ETag:
ETag eTag = new ETag(fileInfo.Name+fileInfo.LastWriteTimeUtc.ToString())

計算ETag值時,需要考慮兩個問題:計算與存儲。如果一個ETag值只需要很小的代價以及占用很低的存儲空間,那么

我們以在每次需要發送給客戶端ETag值值的時候計算一遍就行行了。相反的,我們需要將之前就已經計算並存儲好

的ETag值發送給客戶端。之前說:將時間戳作為字符串作為一種廉價的方式來獲取ETag值。對於不是經常變化的消息,

它是一種足夠好的方案。注意:如果將時間戳做為ETag值,通常不應該用Last-Modified的值。由於HTTP機制中,所

以當我們在通過服務校驗資源狀態時,客戶端不需要進行相應的改動。計算ETag值開銷最大的一般是計算采用哈希算法

獲取資源的表述值。可以只計算資源的哈希值,也可以將頭信息和頭信息的值也包含進去。如果包含頭信息,那么注意

不要包含計算機標識的頭信息。同樣也應該避免包含Expires、Cache-Control和Vary頭信息。注意:在通過哈希算法

計算ETag值時,先要組裝資源的表述。若組裝也比較耗時,可以采用生成GUID的方式。優化ETag值的獲取。

ETag的類型以及他們之間的區別

ETag有兩種類型:強ETag(strong ETag)與弱ETag(weak ETag)。

強ETag表示形式:"22FAA065-2664-4197-9C5E-C92EA03D0A16"。

弱ETag表現形式:w/"22FAA065-2664-4197-9C5E-C92EA03D0A16"。

強、弱ETag類型的出現與Apache務器計算ETag的方式有關。Apache默認通過FileEtag中FileEtag INode Mtime Siz

e的配置自動生成ETag(當然也可以通過用戶自定義的方式)。假設服務端的資源頻繁被修改(如1秒內修改了N次),此時

如果有用戶將Apache的配置改為MTime,由於MTime只能精確到秒,那么就可以避免強ETag在1秒內的ETag總是不同而

頻繁刷新Cache(如果資源在秒級經常被修改,也可以通過Last-Modified來解決)。


ETag與Last-Modified頭信息用途上的區別

按照HTTP標准,Last-Modified只能精確到秒級。ETag的出現可以很好的解決這個問題。在用途上,ETag常與

If-None-Match或者If-Match一起,由客戶端通過HTTP頭信息(包括ETag值)發送給服務端處理。ETag使用如下:

Get /Order/36 Http1.1

If-Match:"22FAA065-2664-4197-9C5E-C92EA03D0A16"

或If-None-Match:"22FAA065-2664-4197-9C5E-C92EA03D0A16"

Last-Modified常與If-Modified-Since一起由客戶端將Last-Modified值包括在HTTP頭信息中發給服務端進行處理。

其使用如下:

If-Modified-Since:Sat,24 Dec 2011 11:55:36 GMT


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM