在瀏覽器第一次請求某一個URL時,服務(wù)器端的返回狀態(tài)200,內(nèi)容是你請求的資源,同時有一個Last-Modified的屬性標(biāo)記(響應(yīng)頭)此文件在服務(wù)器端最后被修改的時間,格式類似這樣:Last-Modified:Tue,24 Feb 2009
客戶端第二次請求此URL時,根據(jù)HTTP協(xié)議的規(guī)定,瀏覽器會向服務(wù)器傳送If-Modified-Since報頭(請求頭),詢問該事件之后文件是否有被修改過,如果服務(wù)器端的資源沒有變化,則自動返回HTTP:304狀態(tài)碼,內(nèi)容為空,這樣就節(jié)省了傳輸數(shù)據(jù)量。當(dāng)服務(wù)器端代碼發(fā)生改變或者重啟服務(wù)器時,則重新發(fā)出資源,返回和第一次請求時類似。從而保證不向客戶端重復(fù)發(fā)出資源,也保證當(dāng)服務(wù)器有變化時,客戶端能夠得到最新的資源。
Etag工作原理
- http協(xié)議規(guī)格說明定義Etag為“被請求變量的實體標(biāo)記”。簡單點即服務(wù)器響應(yīng)時給請求URL標(biāo)記,并在HTTP響應(yīng)頭中將其傳送到客戶端,類似服務(wù)器端返回的格式。
Etag:“5d8c72a5edda8d6a:3239″
客戶端的查詢更新格式是這樣的:
- If-None-Match:“5d8c72a5edda8d6a:3239″
- 如果Etag沒改變,則返回狀態(tài)嗎304
- 即:客戶端發(fā)出請求后,響應(yīng)頭中包含Etag:“5d8c72a5edda8d6a:3239″標(biāo)識,等于告訴客戶端,你拿到的這個資源有標(biāo)識ID:5d8c72a5edda8d6a:3239。
- 當(dāng)下次需要發(fā)請求索要同一個URI的時候,瀏覽器同時發(fā)出一個if-None-Match請求頭,此時報頭中信息包含上次訪問得到的:ID標(biāo)識。
- if-None-Match:5d8c72a5edda8d6a:3239“
- 這樣,客戶端等于緩存了兩份,服務(wù)器端就會比對二者的Etag。如果if-None-Match為False,不返回200,返回304狀態(tài)碼。
Expires
- 給出的日期后,被響應(yīng)認為是過時。需要和Last-Modified結(jié)合使用。用于控制請求文件的有效時間,當(dāng)請求數(shù)據(jù)在有效期內(nèi)時客戶端瀏覽器從緩存請求數(shù)據(jù)而不是服務(wù)器端。當(dāng)緩存中數(shù)據(jù)失效或過期,才決定從服務(wù)器更新數(shù)據(jù)。
如果max-age和Expires同時存在,則被Cache-Control的max-age覆蓋。
[Expires]:
- 描述的是一個絕對時間,根據(jù)的是客戶端時間。用GMT格式字符串表示,如Expires:Thu, 31 Dec 2037 23:55:55 GMT 下次瀏覽器再次請求同一資源時。先從哭護短緩存中尋找,找到這個資源后,拿出它的[Expires]跟當(dāng)前的請求時間比較。如果請求時間在[Expires]指定的失效時間之前,就能命中緩存,這樣就不用再次到服務(wù)器上去緩存一遍,節(jié)省了資源。但是正因為是絕對時間,如果客戶端時間被隨意更改下,這個機制就失效了。所以我們需要[Cache-Control]。
[Cache-Control]
- 描述的是一個相對時間,在進行緩存命中時,都是利用瀏覽器時間判斷。這兩個header可以只啟用一個,也可以同時啟用,當(dāng)response header中,[Expires]和[Cache-Control]同時存在時,[Cache-Control]優(yōu)先級高于[Expires]。
- 當(dāng)瀏覽器對某個資源的請求沒有命中強緩存,就會發(fā)一個強求到服務(wù)器,驗證協(xié)商緩存是否命中。如果命中,則還是從客戶端緩存中加載。協(xié)商緩存利用的是[Last-Modified,If-Modified-Since]和[ETag、If-None-Match]這兩對Header來管理的。
[Last-Modified]:原理和上面的[expires]相同,區(qū)別是它是根據(jù)服務(wù)器時間返回的header來判斷緩存是否存在。但是有時候也會服務(wù)器上資源其實有變化,但是最后修改時間卻沒有變化的情況(這種問題也不容易被定位),這時候我們需要[ETag、If-None-Match]。
[ETag、If-None-Match]:原理與上相同,區(qū)別是瀏覽器跟服務(wù)器請求一個資源,服務(wù)器在返回這個資源的同時,在respone的header加上ETag的header,這個header是服務(wù)器根據(jù)當(dāng)前請求的資源生成的一個唯一標(biāo)識,這個唯一標(biāo)識是一個字符串,只要資源有變化這個串就不同。
[ETag、If-None-Match]這么厲害我們?yōu)槭裁催€需要[Last-Modified、If-Modified-Since]呢?有一個例子就是分布式系統(tǒng)盡量關(guān)閉掉ETag(每臺機器生成的ETag都會不一樣)
[Last-Modified,If-Modified-Since]和[ETag、If-None-Match]一般都是同時啟用。