瀏覽器緩存基本認識
瀏覽器緩存分爲強緩存和協商緩存: 瀏覽器在加載資源時,先根據這個資源的一些http header判斷它是否命中強緩存,強緩存若是命中,瀏覽器直接從本身的緩存中讀取資源,不會發請求到服務器。 當強緩存沒有命中的時候,瀏覽器必定會發送一個請求到服務器,經過服務器端依據資源的另一些http header驗證這個資源是否命中協商緩存,若是協商緩存命中,服務器會將這個請求返回,可是不會返回這個資源的數據,而是告訴客戶端能夠直接從緩存中加載這個資源,因而瀏覽器就又會從本身的緩存中去加載這個資源;web
強緩存與協商緩存的共同點是:
若是命中,都是從客戶端緩存中加載資源,而不是從服務器加載資源數據;瀏覽器
區別是:
強緩存不發請求到服務器,協商緩存會發請求到服務器。 當協商緩存也沒有命中的時候,瀏覽器直接從服務器加載資源數據。緩存
強緩存的原理
當瀏覽器對某個資源的請求命中了強緩存時,返回的http狀態爲200,則直接從緩存中取出資源安全
強緩存是利用Expires或者Cache-Control這兩個http response header實現的,它們都用來表示資源在客戶端緩存的有效期。服務器
Expires
Expires是http1.0提出的一個表示資源過時時間的header,它描述的是一個絕對時間,由服務器返回,code
瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上Expires的header,如:
瀏覽器在接收到這個資源後,會把這個資源連同全部response header一塊兒緩存下來(因此緩存命中的請求返回的header並非來自服務器,而是來自以前緩存的header)
瀏覽器再請求這個資源時,先從緩存中尋找,找到這個資源後,拿出它的Expires跟當前的請求時間比較,若是請求時間在Expires指定的時間以前,就能命中緩存,不然就不行。
若是緩存沒有命中,瀏覽器直接從服務器加載資源時,Expires Header在從新加載的時候會被更新。 Expires是較老的強緩存管理header,因爲它是服務器返回的一個絕對時間,在服務器時間與客戶端時間相差較大時,緩存管理容易出現問題,好比隨意修改下客戶端時間,就能影響緩存命中的結果。
Cache-Control
瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上Cache-Control的header,
瀏覽器在接收到這個資源後,會把這個資源連同全部response header一塊兒緩存下來;
瀏覽器再請求這個資源時,先從緩存中尋找,找到這個資源後,根據它第一次的請求時間和Cache-Control設定的有效期,計算出一個資源過時時間,再拿這個過時時間跟當前的請求時間比較,若是請求時間在過時時間以前,就能命中緩存,不然就不行。
若是緩存沒有命中,瀏覽器直接從服務器加載資源時,Cache-Control Header在從新加載的時候會被更新。 Cache-Control描述的是一個相對時間,在進行緩存命中的時候,都是利用客戶端時間進行判斷,因此相比較Expires,Cache-Control的緩存管理更有效,安全一些。
協商緩存的原理
當瀏覽器對某個資源的請求沒有命中強緩存,就會發一個請求到服務器,驗證協商緩存是否命中,若是協商緩存命中,請求響應返回的http狀態爲304而且會顯示一個Not Modified的字符串cdn
協商緩存是利用的是Last-Modified,If-Modified-Since
和ETag、If-None-Match
這兩對Header來管理的。blog
Last-Modified,If-Modified-Since
瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上Last-Modified的header,這個header表示這個資源在服務器上的最後修改時間:
瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-Modified-Since的header,這個header的值就是上一次請求時返回的Last-Modified的值
服務器再次收到資源請求時,根據瀏覽器傳過來If-Modified-Since和資源在服務器上的最後修改時間判斷資源是否有變化,若是沒有變化則返回304 Not Modified,可是不會返回資源內容;若是有變化,就正常返回資源內容。當服務器返回304 Not Modified的響應時,response header中不會再添加Last-Modified的header,由於既然資源沒有變化,那麼Last-Modified也就不會改變,
瀏覽器收到304的響應後,就會從緩存中加載資源。
若是協商緩存沒有命中,瀏覽器直接從服務器加載資源時,Last-Modified Header
在從新加載的時候會被更新,下次請求時,If-Modified-Since
會啓用上次返回的Last-Modified
值。 Last-Modified,If-Modified-Since
都是根據服務器時間返回的header,通常來講,在沒有調整服務器時間和篡改客戶端緩存的狀況下,這兩個header配合起來管理協商緩存是很是可靠的,可是有時候也會服務器上資源其實有變化,可是最後修改時間卻沒有變化的狀況,而這種問題又很不容易被定位出來,而當這種狀況出現的時候,就會影響協商緩存的可靠性。因此就有了另一對header來管理協商緩存,這對header就是ETag、If-None-Match
ETag、If-None-Match
瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上ETag的header,這個header是服務器根據當前請求的資源生成的一個惟一標識,這個惟一標識是一個字符串,只要資源有變化這個串就不一樣,跟最後修改時間沒有關係,因此能很好的補充Last-Modified的問題:
瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-None-Match的header,這個header的值就是上一次請求時返回的ETag的值
服務器再次收到資源請求時,根據瀏覽器傳過來If-None-Match和而後再根據資源生成一個新的ETag,若是這兩個值相同就說明資源沒有變化,不然就是有變化;若是沒有變化則返回304 Not Modified,可是不會返回資源內容;若是有變化,就正常返回資源內容。與Last-Modified不同的是,當服務器返回304 Not Modified的響應時,因爲ETag從新生成過,response header中還會把這個ETag返回,即便這個ETag跟以前的沒有變化
瀏覽器收到304的響應後,就會從緩存中加載資源。
強緩存與協商緩存的區別:
協商緩存跟強緩存不同,強緩存不發請求到服務器,因此有時候資源更新了瀏覽器還不知道,可是協商緩存會發請求到服務器,因此資源是否更新,服務器確定知道。 大部分web服務器都默認開啓協商緩存,並且是同時啓用【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】,資源
刷新對緩存的影響:
當ctrl+f5強制刷新網頁時,直接從服務器加載,跳過強緩存和協商緩存;
當f5刷新網頁時,跳過強緩存,可是會檢查協商緩存;
瀏覽器地址欄中寫入URL,回車 瀏覽器發現緩存中有這個文件了,不用繼續請求了,直接去緩存拿。(最快)
上述文章僅爲我的總結梳理用,若是有錯誤,歡迎在評論中留言指正~字符串