前段時間去面試移動端的H5開發工程師,在最後面試的時候被問到了max-age Expires Etag有什麼不一樣,在什麼狀況下應用,當時亂編了一通,自我感受良好,結果…… 你們懂得,如今講他們幾個的區別以及如何應用進行一下總結,方便後續查看。css
http/1.0中定義的header,是最基礎的瀏覽器緩存處理,表示資源在必定時間內從瀏覽器的緩存中獲取資源,不須要請求服務器獲取資源,從而達到快速獲取資源,緩解服務器壓力的目的。html
在response的header中的格式爲:Expires: Thu, 01 Dec 1994 16:00:00 GMT (必須是GMT格式)node
應用:
一、能夠在html頁面中添加<meta http-equiv="Expires" content="Thu, 01 Dec 1994 16:00:00"/> 來給頁面設置緩存時間。
二、對於圖片、css等文件則須要在IIS或者apache等運行容器中進行規則配置來讓容器在請求資源的時候添加在responese的header中。面試
望文知義,根據這個詞條的直譯應該是上次修改(時間),經過修改服務器端的文件後再請求,發現response的header中的Last-modified改變了apache
更新原理:
一、在瀏覽器首次請求某個資源時,服務器端返回的狀態碼是200 (ok),內容是你請求的資源,同時有一個Last-Modified的屬性標記(Reponse Header),標識此文件在服務期端最後被修改的時間,格式:Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT瀏覽器
二、瀏覽器第二次請求該資源時,根據HTTP協議的規定,瀏覽器會向服務器傳送If-Modified-Since報頭(Request Header),詢問該文件是否在指定時間以後有被修改過,格式爲:If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT緩存
三、若是服務器端的資源沒有變化,則服務器返回304狀態碼(Not Modified),內容爲空,這樣就節省了傳輸數據量。當服務器端代碼發生改變,則服務器返回200狀態碼(ok),內容爲請求的資源,和第一次請求資源時相似。從而保證在資源沒有修改時不向客戶端重複發出資源,也保證當服務器有變化時,客戶端可以及時獲得最新的資源。服務器
注:若是If-Modified-Since的時間比服務器當前時間(當前的請求時間request_time)還晚,會認爲是個非法請求負載均衡
http/1.1 中增長的header,HTTP協議規格說明定義ETag爲「被請求變量的實體值」 。另外一種說法是,ETag是一個能夠與Web資源關聯的記號(token)。典型的Web資源能夠一個Web頁,但也多是JSON或XML文檔。服務器單獨負責判斷記號是什麼及其含義,並在HTTP響應頭中將其傳送到客戶端。分佈式
ETag的格式
不一樣類型的Web服務器生成ETag的策略以及生成的格式是不一樣的:
一、apache1.3和2.x的Etag格式是:inode-size-timestamp。
二、IIS5.0和6.0的Etag格式爲Filetimestamp:Changenumber。
更新原理:
一、當瀏覽器首次請求資源的時候,服務器會返回200的狀態碼(ok),內容爲請求的資源,同時response header會有一個ETag標記,該標記是服務器端根據容器(IIS或者Apache等等)中配置的ETag生成策略生成的一串惟一標識資源的字符串,ETag格式爲 ETag:"856247206"
二、當瀏覽器第2次請求該資源時,瀏覽器會在傳遞給服務器的request中添加If-None-Match報頭,詢問服務器改文件在上次獲取後是否修改了,報頭格式:If-None-Match:"856246825"
三、服務器在獲取到瀏覽器的請求後,會根據請求的資源查找對應的ETag,將當前服務器端指定資源對應的Etag與request中的If-None-Match進行對比,若是相同,說明資源沒有修改,服務器返回304狀態碼(Not Modified),內容爲空;若是對比發現不相同,則返回200狀態碼,同時將新的Etag添加到返回瀏覽器的response中。
Cache-Control中設置資源在本地緩存時間的一個值,單位爲:秒(s),其餘值還有private、no-cache、must-revalidate等
Expires存在HTTP 1.0 版本, 標識本地緩存的截止時間,容許瀏覽器在這個時間以前不去向服務器端發送請求驗證資源是否有更新
max-age是HTTP 1.1版本新增的, 標識資源能夠在本地緩存多少秒,存儲的是更新間隔。
Expires 的一個缺點就是,返回的到期時間是服務器端的時間,這樣存在一個問題,若是瀏覽器所在機器的時間與服務器的時間相差很大,那麼偏差就很大,因此在HTTP 1.1版開始,使用Cache-Control: max-age替代。
注: 若是max-age和Expires同時存在,則被Cache-Control的max-age覆蓋。
Expires =max-age + 「每次下載時的當前的request時間」
因此一旦從新下載的頁面後,expires就從新計算一次,但last-modified不會變化
使用Last-Modified標識因爲在資源未修改時返回的response內容爲空,能夠節省一點帶寬,可是仍是逃不掉髮一個HTTP請求出去,須要瀏覽器鏈接一次服務器端。
而Expires標識卻使得瀏覽器乾脆連HTTP請求都不用發,可是當用戶使用F5或者點擊Refresh按鈕的時候,就算URI設置了Expires,瀏覽器同樣也會發一個HTTP請求給服務器端,因此,Last-Modified仍是要用的,並且要和Expires一塊兒用。
和 Last-Modified和Expires的狀況相似,須要Expires控制請求的頻率,Etag在強制刷新時做爲保障
分佈式系統裏多臺機器間文件的last-modified必須保持一致,以避免負載均衡到不一樣機器致使比對失敗,通常建議分佈式系統儘可能關閉掉Etag(每臺機器生成的etag都會不同)
Last-Modified和ETags請求的http報頭一塊兒使用,服務器首先產生Last-Modified/Etag標記,服務器可在稍後使用它來判斷頁面是否已經被修改,來決定文件是否繼續緩存
過程以下:
1.客戶端請求一個頁面(A)。
2.服務器返回頁面A,並在給A加上一個Last-Modified/ETag。
3.客戶端展示該頁面,並將頁面連同Last-Modified/ETag一塊兒緩存。
4.客戶再次請求頁面A,並將上次請求時服務器返回的Last-Modified/ETag一塊兒傳遞給服務器。
5.服務器檢查該Last-Modified或ETag,並判斷出該頁面自上次客戶端請求以後還未被修改,直接返回響應304和一個空的響應體。
從資源更新原理來看Last-Modified和Etag基本是相似的,那爲何http協議中要搞2個標識呢?
Last-Modified存在的問題:一、在集羣服務器上各個服務器上的文件時間可能不一樣。二、若是用舊文件覆蓋新文件,由於時間更前,瀏覽器不會請求這個更舊的文件。三、時間精度爲s級,對文件修改精度有嚴格要求的場景不能知足