HTTP協議規格說明定義ETag爲「被請求
變量的實體值」。另外一種說法是,ETag是一個能夠與Web資源關聯的記號(token)。典型的Web資源能夠一個Web頁,但也多是JSON或XML文檔。服務器單獨負責判斷記號是什麼及其含義,並在HTTP響應頭中將其傳送到
客戶端, 如下是服務器端返回的格式:ETag:"50b1c1d4f775c61:df3"客戶端的查詢更新格式是這樣的:If-None-Match : W / "50b1c1d4f775c61:df3"若是ETag沒改變,則返回狀態304而後不返回,這也和Last-Modified同樣。測試Etag主要 在斷點下載時比較有用。
Etag
[1]
是URL的Entity Tag,用於標示URL對象是否改變,區分不一樣語言和
Session等等。具體內部含義是使
服務器控制的,就像
Cookie那樣。
HTTP協議規格說明定義ETag爲「被請求
變量的實體值」。另外一種說法是,ETag是一個能夠與Web資源關聯的記號(token)。典型的Web資源能夠一個Web頁,但也多是JSON或XML文檔。服務器單獨負責判斷記號是什麼及其含義,並在HTTP響應頭中將其傳送到
客戶端, 如下是服務器端返回的格式:ETag:"50b1c1d4f775c61:df3"客戶端的查詢更新格式是這樣的:If-None-Match : W / "50b1c1d4f775c61:df3"若是ETag沒改變,則返回狀態304而後不返回,這也和Last-Modified同樣。測試Etag主要 在斷點下載時比較有用。
性能
聰明的服務器開發者會把ETags和GET請求的「If-None-Match」頭一塊兒使用,這樣可利用客戶端(例如瀏覽器)的緩存。由於服務器首先產生ETag,服務器可在稍後使用它來判斷頁面是否已經被修改。本質上,
客戶端經過將該記號傳回服務器要求服務器驗證其(客戶端)緩存。
其過程以下:
客戶端請求一個頁面(A)。 服務器返回頁面A,並在給A加上一個ETag。 客戶端展示該頁面,並將頁面連同ETag一塊兒緩存。 客戶再次請求頁面A,並將上次請求時服務器返回的ETag一塊兒傳遞給服務器。 服務器檢查該ETag,並判斷出該頁面自上次客戶端請求以後還未被修改,直接返回響應304(未修改——Not Modified)和一個空的響應體。
優點
一、 有些URL是多語言的網頁,相同的URL會返回不一樣的東東。還有不一樣的Session有不一樣的Cookie也就有不一樣的內容。這種狀況下若是過 Proxy,Proxy就沒法區分致使串門,只能簡單的取消cache功能。Etag解決了這個問題,由於它能區分相同URL不一樣的對象。
二、老的
HTTP標 準裏有個Last-Modified+If-Modified-Since代表URL對象是否改變。Etag也具備這種功能,由於對象改變也形成Etag 改變,而且它的控制更加準確。Etag有兩種用法 If-Match/If-None-Match,就是若是服務器的對象和客戶端的對象ID(不)匹配才執行。這裏的If-Match/If-None- Match都能一次提交多個Etag。If-Match能夠在Etag未改變時斷線重傳。If-None-Match能夠刷新對象(在有新的Etag時返 回)。
三、Etag中有種Weak Tag,值爲 W/"xxxxx"。他聲明Tag是弱匹配的,只能作模糊匹配,在差別達到必定閥值時才起做用。
四、Etag對於cache CGI頁面頗有用。特別是論壇,論壇有辦法爲每一個帖子頁面生成惟一的Etag,在帖子未改變時,查看話題屬性比較Etag就能避免刷新帖子,減小CGI操做和
網絡傳輸。好比論壇中看帖就返回Etag,減小論壇負擔。
五、Etag在不一樣URL之間沒有可比性,也就是不一樣URL相同Etag沒有特別意義。
請求流程
Etag由服務器端生成,客戶端經過If-Match或者說If-None-Match這個條件判斷請求來驗證資源是否修改。常見的是使用If-None-Match.請求一個文件的流程可能以下:
====第一次請求===
1.客戶端發起 HTTP GET 請求一個文件;
2.服務器處理請求,返回文件內容和一堆Header,固然包括Etag(例如"2e681a-6-5d044840")(假設服務器支持Etag生成和已經開啓了Etag).狀態碼200
====第二次請求===
1.客戶端發起 HTTP GET 請求一個文件,注意這個時候客戶端同時發送一個If-None-Match頭,這個頭的內容就是第一次請求時服務器返回的Etag:2e681a-6-5d044840
2.服務器判斷髮送過來的Etag和計算出來的Etag匹配,所以If-None-Match爲False,不返回200,返回304,客戶端繼續使用
本地緩存;
流程很簡單,問題是,若是服務器又設置了Cache-Control:max-age和Expires呢,怎麼辦?
答案是同時使用,也就是說在徹底匹配If-Modified-Since和If-None-Match即檢查完修改時間和Etag以後,服務器才能返回304.(不要陷入到底使用誰的問題怪圈)
做用
Etag 主要爲了解決 Last-Modified 沒法解決的一些問題。
一、一些文件也許會週期性的更改,可是他的內容並不改變(僅僅改變的修改時間),這個時候咱們並不但願客戶端認爲這個文件被修改了,而從新GET;
二、某些文件修改很是頻繁,好比在秒如下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改沒法判斷(或者說UNIX記錄MTIME只能精確到秒)
三、某些服務器不能精確的獲得文件的最後修改時間;
爲此,HTTP/1.1引入了 Etag(Entity Tags).Etag僅僅是一個和文件相關的標記,能夠是一個版本標記,好比說v1.0.0或者說"2e681a-6-5d044840"這麼一串看起來 很神祕的編碼。可是HTTP/1.1標準並無規定Etag的內容是什麼或者說要怎麼實現,惟一
規定的是Etag須要放在""內。
Apache
[2]
首先判斷是否是弱Etag,這個留在下面講。若是不是,進入第二種狀況:
強Etag根據配置文件中的配置來設置Etag值,默認的Apache的FileEtag設置爲:
FileEtag INode Mtime Size
也就是根據這三個屬性來生成Etag值,他們之間經過一些算法來實現,並輸出成
hex的格式,相鄰屬性之間用-分隔,好比:
Etag"2e681a-6-5d044840"
這裏面的三個段,分別表明了
INode,
MTime,
Size根據算法算出的值的Hex格式,(若是在這裏看到了非Hex裏面的字符(也就是0-f),那你可能看見神了:))
固然,能夠改變Apache的FileEtag設置,好比設置成FileEtagSize,那麼獲得的Etag可能爲:
Etag"6"
總之,設置了幾個段,Etag值就有幾個段。(不要誤覺得Etag就是固定的3段式)
說明:這裏說的都是Apache2.2裏面的Etag實現,由於HTTP/1.1並無規定Etag必須是什麼樣的 實現或者格式,所以,也能夠修改或者徹底編寫本身的算法獲得Etag,好比"2e681a65d044840",客戶端會記住並緩存下這個 Etag(Windows裏面保存在哪裏,下次訪問的時候直接拿這個值去和服務器生成的Etag對比。
注意:無論怎麼樣的算法,在服務器端都要進行計算,計算就有開銷,會帶來性能損失。所以爲了榨乾這一點點性能,很多網站徹底把Etag禁用了(好比Yahoo!),這其實不符合HTTP/1.1的規定,由於HTTP/1.1老是鼓勵服務器儘量的開啓Etag。