Etag在HTTP1.1中有介紹,主要的做用就是在(css file, image, javascript file)文件後面添加一個惟一的參數(至關於查詢參數字符串),Etag有服務器端生成,而且隨着文件的改變而改變,這樣瀏覽器端就會只從新請求獲取Etag發生變化的文件,減小瀏覽器端數據的流量,加快瀏覽器的反應速度,重要的是減輕服務器端的壓力,因此服務器端Etag的實現就比較重要了. javascript
如今咱們有個問題爲何要使用Etag呢? css
Etag主要爲了解決Last-Modified沒法解決的一些問題.他能比Last_Modified更加精確的知道文件是否被修改過.若是有個文件修改很是頻繁,好比在秒如下的時間內進行修改,好比1秒內修改了10次,If-Modified-Since能檢查只能秒級的修改,因此這種修改沒法判斷.緣由是UNIX記錄MTIME只能精確到秒.因此咱們選擇生成Etag,由於Etag能夠綜合Inode,MTime和Size,能夠避免這個問題. java
Etag的工做原理
Etag在服務器上生成後,客戶端經過If-Match或者說If-None-Match這個條件判斷請求來驗證資源是否修改.咱們常見的是使用If-None-Match.請求一個文件的流程可能以下:
新的請求
客戶端發起HTTP GET請求一個文件(css ,image,js);服務器處理請求,返回文件內容和一堆Header(包括Etag,例如"2e681a-6-5d044840"),http頭狀態碼爲爲200. node
同一個用戶第二次這個文件的請求
客戶端在一次發起HTTP GET請求一個文件,注意這個時候客戶端同時發送一個If-None-Match頭,這個頭中會包括上次這個文件的Etag(例如"2e681a-6-5d044840"),這時服務器判斷髮送過來的Etag和本身計算出來的Etag,所以If-None-Match爲False,不返回200,返回304,客戶端繼續使用本地緩存; apache
注意.服務器又設置了Cache-Control:max-age和Expires時,會同時使用,也就是說在徹底匹配If-Modified-Since和If-None-Match即檢查完修改時間和Etag以後,服務器才能返回304. 瀏覽器
下面是在Apache中的Etag的配置 緩存
在Apache中設置Etag的支持比較簡單,只須要在apache的配置中加入下面的內容就能夠了: 服務器
FileETag MTime Size 網絡
註解:FileETag指令配置了當文檔是基於一個文件時用以建立ETag(實體標籤)應答頭的文件的屬性(ETag的值用於進行緩衝管理以節約網絡帶寬).ETag的值由文件的inode(索引節點)、大小、最後修改時間決定.FileETag指令可讓您選擇(若是您想進行選擇)這其中哪些要素將被使用.主要關鍵字以下: 索引
INode
文件的索引節點(inode)數
MTime
文件的最後修改日期及時間
Size
文件的字節數
All
全部存在的域,等價於:FileETag INode MTime Size
None
若是一個文檔是基於文件的,則不在應答中包含任何ETag頭
在大型多WEB集羣時,使用ETag時有問題,因此有人建議使用WEB集羣時不要使用ETag,其實很好解決,由於多服務器時,INode不同,因此不一樣的服務器生成的ETag不同,因此用戶有可能重複下載(這時ETag就會不許),明白了上面的原理和設置後,解決方法也很容易,讓ETag後面二個參數,MTime和Size就行了.只要ETag的計算沒有INode參於計算,就會很準了