瀏覽器緩存

1. 思路1,無緩存

瀏覽器向服務器請求資源 a.jpg,服務器找到對應資源把內(nèi)容返回給瀏覽器。當瀏覽器再次向服務器請求資源a.jpg時,服務器重新發(fā)送完整的數(shù)據(jù)文件給瀏覽器。

  • 優(yōu)點:簡單,啥都不用做
  • 缺點:每次請求都查找并返回原始文件,浪費帶寬(1990年的帶寬很貴?。?/li>

2. 思路2,有緩存無更新

瀏覽器第一次請求a.jpg 時服務器會發(fā)送完整的文件,瀏覽器可以把這個文件存到本地(緩存),下次再需要這個文件時直接從本地獲取就行了,這樣就能省下帶寬了。

  • 優(yōu)點: 省帶寬
  • 缺點: 如果服務器上a.jpg的文件內(nèi)容變了,瀏覽器每次都從緩存讀取無法獲取最新文件

3. 思路3, 緩存+更新機制

瀏覽器第一次請求a.jpg 時服務器會發(fā)送完整的文件,服務器在發(fā)送文件的時候還附帶發(fā)送一些額外信息——過期時間,如Expires: Mon,10 Dec 1990 02:25:22GMT。瀏覽器可以把這個文件和額外信息存到本地。當再次需要a.jpg的時候瀏覽器用當前瀏覽器時間和Expires做個比較,如果當前時間在過期時間以內(nèi),就直接使用緩存文件((200, from xx cache);如果在過期時間以外就重新向服務器發(fā)送請求要資源(200)。 服務器在每次給資源的時候都會發(fā)送新的過期時間

  • 優(yōu)點:緩存可控制
  • 缺點:控制的功能太單一;這種格式的時間很容易寫錯

4. 思路4, 緩存+更新機制升級版

比如:瀏覽器第一次請求a.jpg 時,服務器會發(fā)送完整的文件并附帶額外信息

Cache-Control: max-age=300
瀏覽器把文件和附帶信息保存起來。當再次需要a.jpg 時,如果是在300秒以內(nèi)發(fā)起的請求則直接使用緩存(200, from xx cache),否則重新發(fā)起網(wǎng)絡請求(200)。下面是Cache-Control常見的幾個值

  1. Public表示響應可被任何中間節(jié)點緩存,如 Browser <-- proxy1 <-- proxy2 <-- Server,中間的proxy可以緩存資源,比如下次再請求同一資源proxy1直接把自己緩存的東西給 Browser 而不再向proxy2要。
  2. Private表示中間節(jié)點不允許緩存,對于Browser <-- proxy1 <-- proxy2 <-- Server,proxy 會老老實實把Server 返回的數(shù)據(jù)發(fā)送給proxy1,自己不緩存任何數(shù)據(jù)。當下次Browser再次請求時proxy會做好請求轉(zhuǎn)發(fā)而不是自作主張給自己緩存的數(shù)據(jù)。
  3. no-cache表示不使用 Cache-Control的緩存控制方式做前置驗證,而是使用 Etag 或者Last-Modified字段來控制緩存
  4. no-store ,真正的不緩存任何東西。瀏覽器會直接向服務器請求原始文件,并且請求中不附帶 Etag 參數(shù)(服務器認為是新請求)。
  5. max-age,表示當前資源的有效時間,單位為秒。
  • 優(yōu)點:緩存控制功能更強大
  • 缺點:假如瀏覽器再次請求資源a.jpg的時間間隔超過了max-age,這時候向服務器發(fā)送請求服務器應該會重新返回a.jpg的完整文件。但如果 a.jpg 在服務器上未做任何修改,發(fā)送a.jpg的完整文件就太浪費帶寬了,其實只要發(fā)送一個「a.jpg未被更改」的短消息標示就好了。

5. 思路5, 緩存+更新機制終極版

比如:瀏覽器第一次請求a.jpg 時,服務器會發(fā)送完整的文件并附帶額外信息,其中Etag 是 對a.jpg文件的編碼,如果a.jpg在服務端未被修改,這個值就不會變

Cache-Control: max-age=300
ETag:W/"e-cbxLFQW5zapn79tQwb/g6Q"

瀏覽器把a.jpg和額外信息保存到本地。假如瀏覽器在300秒以內(nèi)再次需要獲取a.jpg時,瀏覽器直接從緩存讀取a.jpg(200, from xx cache)。假如瀏覽器在300秒之后再次需要獲取a.jpg時,瀏覽器發(fā)現(xiàn)該緩存的文件已經(jīng)不新鮮了,于是就向服務器發(fā)送請求 重新獲取a.jpg.
在發(fā)送請求的時候附帶剛剛保存的a.jpg的ETag ( If-None-Match:W/"e-cbxLFQW5zapn79tQwb/g6Q")。 服務器在接收到請求后拿瀏覽器請求的 Etag 和當前文件重新計算后端 Etag 做個比較,
如果二者相等表示文件在未修改則發(fā)送個短消息(響應頭,不包含圖片內(nèi)容, 304),
如果二者不等則發(fā)送新文件和新的 ETag,瀏覽器獲取新文件并更新該文件的 Etag。

與 ETag 類似功能的是Last-Modified/If-Modified-Since。當資源過期時(max-age超時),發(fā)現(xiàn)資源具有Last-Modified聲明,則再次向web服務器請求時帶上頭 If-Modified-Since,表示請求時間。web服務器收到請求后發(fā)現(xiàn)有頭If-Modified-Since 則與被請求資源的最后修改時間進行比對。若最后修改時間較新,說明資源又被改動過,則響應整片資源內(nèi)容(200);若最后修改時間較舊,說明資源無新修改,則響應HTTP 304 ,告知瀏覽器繼續(xù)使用所保存的cache。

總結(jié)

瀏覽器緩存控制分為強緩存和協(xié)商緩存,協(xié)商緩存必須配合強緩存使用。
首先瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源和response header的同時,會根據(jù)開發(fā)者要求或者瀏覽器默認,在response的header加上相關(guān)字段的http response header。

一、當瀏覽器對某個資源的請求命中了強緩存時,利用[Expires]或者[Cache-Control]這兩個http response header實現(xiàn) 。

  • [Expires]:描述的是一個絕對時間,根據(jù)的是客戶端時間。用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2037 23:55:55 GMT 下次瀏覽器再次請求同一資源時。先從客戶端緩存中尋找,找到這個資源后,拿出它的[Expires]跟當前的請求時間比較。如果請求時間在[Expires]指定的失效時間之前,就能命中緩存,這樣就不用再次到服務器上去緩存一遍,節(jié)省了資源。但是正因為是絕對時間,如果客戶端時間被隨意更改下,這個機制就失效了。所以我們需要[Cache-Control]。
  • [Cache-Control]:描述的是一個相對時間,在進行緩存命中時,都是利用瀏覽器時間判斷。
    這兩個header可以只啟用一個,也可以同時啟用,當response header中,[Expires]和[Cache-Control]同時存在時,[Cache-Control]優(yōu)先級高于[Expires]。

二、當瀏覽器對某個資源的請求沒有命中強緩存,就會發(fā)一個請求到服務器,驗證協(xié)商緩存是否命中。 如果命中,則還是從客戶端緩存中加載。協(xié)商緩存利用的是[Last-Modified,If-Modified-Since]和[ETag、If-None-Match]這兩對Header來管理的。

  • [Last-Modified]:原理和上面的[expires]相同,區(qū)別是它是根據(jù)服務器時間返回的header來判斷緩存是否存在。但是有時候也會服務器上資源其實有變化,但是最后修改時間卻沒有變化的情況(這種問題也不容易被定位),這時候我們需要[ETag、If-None-Match]。
  • [ETag、If-None-Match]:原理與上相同,區(qū)別是瀏覽器跟服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上ETag的header,這個header是服務器根據(jù)當前請求的資源生成的一個唯一標識,這個唯一標識是一個字符串,只要資源有變化這個串就不同。
    [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]一般都是同時啟用。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容