天天看點

浏覽器緩存機制Expires政策 Cache-control政策(重點關注) 既生Last-Modified何生Etag?使用者行為與緩存總結

浏覽器緩存機制

浏覽器緩存機制,其實<b>主要就是</b><b>http</b><b>協定定義的緩存機制(如: expires</b><b>; cache-control</b><b>等)</b>。但是也有非http協定定義的緩存機制,如使用html meta 标簽,web開發者可以在html頁面的&lt;head&gt;節點中加入&lt;meta&gt;标簽,代碼如下:

<b>html code</b>

<b>&lt;meta http-equiv="pragma" content="no-cache"&gt;</b>

上述代碼的作用是告訴浏覽器目前頁面不被緩存,每次通路都需要去伺服器拉取。使用上很簡單,但隻有部分浏覽器可以支援,而且所有緩存代理伺服器都不支援,因為代理不解析html内容本身。

<b>下面我主要介紹http</b><b>協定定義的緩存機制。</b>

expires是web伺服器響應消息頭字段,在響應http請求時告訴<b>浏覽器在過期時間前</b>浏覽器可以直接從浏覽器緩存取資料,而無需再次請求。

下面是寶寶pk項目中,浏覽器拉取jquery.js web伺服器的響應頭:

浏覽器緩存機制Expires政策 Cache-control政策(重點關注) 既生Last-Modified何生Etag?使用者行為與緩存總結

注:date頭域表示消息發送的時間,時間的描述格式由rfc822定義。例如,date: mon,31 dec 2001 04:25:57gmt。

web伺服器告訴浏覽器在2012-11-28 03:30:01這個時間點之前,可以使用緩存檔案。發送請求的時間是2012-11-28 03:25:01,即緩存5分鐘。

不過expires 是http 1.0的東西,現在預設浏覽器均預設使用http 1.1,是以它的作用基本忽略。

cache-control與expires的作用一緻,都是指明目前資源的<b>有效期</b>,控制浏覽器是否直接從浏覽器緩存取資料還是重新發請求到伺服器取資料。隻不過cache-control的<b>選擇更多,設定更細緻</b>,如果同時設定的話,其<b>優先級高于</b><b>expires</b>。

<b>http</b><b>協定頭cache-control    </b><b>:</b>

<b>值可以是public</b><b>、private</b><b>、no-cache</b><b>、no- store</b><b>、no-transform</b><b>、must-revalidate</b><b>、proxy-revalidate</b><b>、max-age</b>

<b>各個消息中的指令含義如下:</b>

<b>public</b><b>訓示響應可被任何緩存區緩存。</b>

<b>private</b><b>訓示對于單個使用者的整個或部分響應消息,不能被共享緩存處理。這允許伺服器僅僅描述當使用者的部分響應消息,此響應消息對于其他使用者的請求無效。</b>

<b>no-cache</b><b>訓示請求或響應消息不能緩存</b>

<b>no-store</b><b>用于防止重要的資訊被無意的釋出。在請求消息中發送将使得請求和響應消息都不使用緩存。</b>

<b>max-age</b><b>訓示客戶機可以接收生存期不大于指定時間(以秒為機關)的響應。</b>

<b>min-fresh</b><b>訓示客戶機可以接收響應時間小于目前時間加上指定時間的響應。</b>

<b>max-stale</b><b>訓示客戶機可以接收超出逾時期間的響應消息。如果指定max-stale</b><b>消息的值,那麼客戶機可以接收超出逾時期指定值之内的響應消息。</b>

還是上面那個請求,web伺服器傳回的cache-control頭的值為max-age=300,即5分鐘(和上面的expires時間一緻,這個不是必須的)。

浏覽器緩存機制Expires政策 Cache-control政策(重點關注) 既生Last-Modified何生Etag?使用者行為與緩存總結

last-modified/if-modified-since要配合cache-control使用。

l  last-modified:标示這個響應資源的最後修改時間。web伺服器在響應請求時,告訴浏覽器資源的最後修改時間。

l  if-modified-since:當資源過期時(使用cache-control辨別的max-age),發現資源具有last-modified聲明,則再次向web伺服器請求時帶上頭 <b>if-modified-since</b>,表示請求時間。<b>web</b><b>伺服器收到請求後發現有頭if-modified-since </b><b>則與被請求資源的最後修改時間進行比對</b>。若最後修改時間較新,說明資源又被改動過,則響應整片資源内容(寫在響應消息包體内),http 200;若最後修改時間較舊,說明資源無新修改,則響應http 304 (無需包體,節省浏覽),告知浏覽器繼續使用所儲存的cache。

etag/if-none-match也要配合cache-control使用。

l  etag:web伺服器響應請求時,告訴浏覽器目前資源在伺服器的唯一辨別(生成規則由伺服器覺得)。apache中,etag的值,預設是對檔案的索引節(inode),大小(size)和最後修改時間(mtime)進行hash後得到的。

l  if-none-match:當資源過期時(使用cache-control辨別的max-age),發現資源具有etage聲明,則再次向web伺服器請求時帶上頭if-none-match<b> </b><b>(etag</b><b>的值)</b>。<b>web</b><b>伺服器收到請求後發現有頭if-none-match </b><b>則與被請求資源的相應校驗串進行比對,決定傳回200</b><b>或304</b>。

你可能會覺得使用last-modified已經足以讓浏覽器知道本地的緩存副本是否足夠新,為什麼還需要etag(實體辨別)呢?http1.1中etag的出現主要是為了解決幾個last-modified比較難解決的問題:

l  last-modified标注的最後修改隻能精确到秒級,如果某些檔案在1秒鐘以内,被修改多次的話,它将不能準确标注檔案的修改時間

l  如果某些檔案會被定期生成,當有時内容并沒有任何變化,但last-modified卻改變了,導緻檔案沒法使用緩存

l  有可能存在伺服器沒有準确擷取檔案修改時間,或者與代理伺服器時間不一緻等情形

etag是伺服器自動生成或者由開發者生成的對應資源在伺服器端的唯一辨別符,能夠更加準确的控制緩存。<b>last-modified</b><b>與etag</b><b>是可以一起使用的,伺服器會優先驗證etag</b><b>,一緻的情況下,才會繼續比對last-modified</b><b>,最後才決定是否傳回304</b>。

浏覽器緩存行為還有使用者的行為有關!!!

<b>使用者操作</b>

<b>expires/cache-control</b>

<b>last-modified/etag</b>

<b>位址欄回車</b>

有效

<b>頁面連結跳轉</b>

<b>新開視窗</b>

<b>前進、後退</b>

<b>f5</b><b>重新整理</b>

無效

<b>ctrl+f5</b><b>重新整理</b>

浏覽器第一次請求:

浏覽器緩存機制Expires政策 Cache-control政策(重點關注) 既生Last-Modified何生Etag?使用者行為與緩存總結

浏覽器再次請求時:

浏覽器緩存機制Expires政策 Cache-control政策(重點關注) 既生Last-Modified何生Etag?使用者行為與緩存總結

繼續閱讀