我們在web開發中常常會遇到這樣的場景,有一些較大和常用的資源(例如、文件、js、css),在頁面開啟初始化的時候並不需要用到,而是在使用者與頁面互動操作觸發了某些條件時才需要這些資源(例如我們開啟微博可能並不是為了看熱搜,但大多數時候我們會點進熱搜查看熱搜新聞)。
強制快取:在http1.0時代,當客戶端根據位址去獲取、文件等快取資源時,我們通過設定響應頭中的expires欄位來給定乙個時間點,並與放在響應體中的請求資源一同返回給客戶端瀏覽器,並一起被儲存於快取中,下次我們再請求同乙個路徑位址拿資源時,瀏覽器強制請求從快取中獲取並返回200狀態碼。當瀏覽器的本地時間超過expires欄位設定的時間,快取資源失效,再請求這個路徑時需要去服務端重新獲取資源。
協商快取:對於一些可能變化較大的資源,我們需要他們及時作出更新,但是又想繼續使用快取這種高效的方式,此時我們便不再使用expires,而是使用last-modified欄位,用來記錄乙個資源的最後改動時間,同樣將該字段連同資源一起發返回給客戶端。瀏覽器第二次請求該路徑時,順帶把該字段值放入請求頭中,不過此時會換乙個欄位名,變成if-modified-since,若伺服器的資源發生變化,那這個資源檔案肯定會有乙個新的變化修改時間,伺服器將新時間與舊時間一對比,發現不一致,將新資源放到響應體,新時間放入響應頭,返回給客戶端,客戶端對快取資源作出更新,狀態碼為200。若新時間與舊時間一致,說明資源未變化,返回狀態碼304 not modified,瀏覽器收到後,便可從快取中取資源。下面是詳細的步驟流程:
1⃣️. 客戶端根據具體路徑獲取資源,此時伺服器端會將該資源的一些基本資訊自動封裝http物件(包含響應頭,響應體),
expires 表示該資源什麼時候過期,last-modified表示該資源最後修改時間。
2⃣️. 瀏覽器拿到資源時,放入快取中,等待使用者使用。
3⃣️. 當使用者使用功能需要該資源時,先檢查是強制快取還是協商快取,前者則直接取,若兩者都有last-modified、expires同時存在,以強制快取優先。若只是協商快取則再次向伺服器傳送相同路徑的請求,此時的請求頭中附帶上該資源的最後修改時間
。4⃣️
. 伺服器根據路徑,檢查最新資源的基本資訊,是否與請求的基本資訊一致。若一致,返回結果304 notmodified,此時伺服器不再返回資源,而是再冗餘返回乙份基本資訊,表示客戶端快取資源可用。
若不一致,則返回狀態碼200和最新資源,還有最新資源的基本資訊。
當請求失敗,也就是後台伺服器掛掉的時候,這裡也是返回304,繼續使用快取舊資源。
http1.0返回304示例如下:
在上張中我們發現返回頭中有cache-control,etag這些字段,其實這些也是伺服器端對瀏覽器作快取控制用到的字段,只不過是後來公升級換代新加入的。在使用http1.0的時候我們發現,當本地時間與伺服器端的時間不一致,或者是部署集群時,地域跨度太大,很容易引起快取失效的問題,而且同時有兩份修改時間一致的檔案互相進行替換的時候,我們很難及時在瀏覽器端作出響應。因此我們在想,能不能直接設定乙個時間段,而不是時間點的方式來對資源有效去作校驗,使用資源內容的雜湊值、雜湊值去校驗資源變化,這便是http1.1。在http1.1中,還是會分為強制快取、協商快取兩種方式,只不過對時間、內容的校驗方法做了優化。
強制快取:1⃣️客戶端請求位址路徑第一次獲取資源,此時伺服器端在響應頭中設定放入兩個字段:age和cache-control。age用來表示資源在客戶端快取中存在了多久,因為是第一次獲取到的資源,所以初始化為0。cache-control用來表示資源有效期,即它能在客戶端快取中存在多久,例如cache-control:max-age=3600 表示3600秒內,快取中的資源都是有效的可以直接使用的。
2⃣️在3600秒內,客戶端請求相同路徑時,強制從快取獲取,並返回狀態碼200。
3⃣️一旦資源佔據快取的時間超過3600秒,客戶端重新從伺服器獲取資源,返回狀態碼200。
協商快取:1⃣️客戶端第一次獲取資源時,伺服器在返回頭放入欄位cache-control和etag。此時的cache-control與強制快取的有點不同,不再是max-age和時間段,而是乙個字串固定值"no-cache"。etag中放入的值一般為資源內容的雜湊或者雜湊值。與返回體中的資源一同返回給客戶端,並將其持久化至快取。
2⃣️客戶端需要再次用到這個位址路徑下的資源時,先去快取中檢視該資源的cache-control的值,發現為"no-cache",這時客戶端知道了,需要先去後台做資源是否發生變化的校驗,於是將該資源的etag值發給後台,這裡etag的欄位名發生變化,變成if-none-match。
3⃣️後台接收請求舊etag後與最新的etag進行比較,若一致,返回304,若不一致,返回200,並在響應體中放乙份最新資源,響應頭中放乙份最新etag。
4⃣️強制快取與協商快取並存時:即cache-control值為"max-age=3600,no-cache",以強制快取優先。
注:在上圖中我們發現1.0和1.1兩種寫法並存,其實是為了更好的相容低版本瀏覽器,因為兩個版本各自校驗並不衝突。
參考資料:
瀏覽器快取機制個人理解
瀏覽器快取究竟有什麼作用呢?在這裡我將瀏覽器快取的作用簡單地歸結為以下幾點。加快頁面開啟速度 降低伺服器壓力 減少網路損耗 瀏覽器快取有 html meta 標籤控制 一般不用,所以本文不介紹 與 http 頭資訊控制兩種。快取標識字段便是expires和cache control。expires ...
瀏覽器快取機制
最近在準備優化日誌請求時遇到了一些令人疑惑的問題,比如為什麼響應頭里出現了兩個 cache control 為什麼明明設定了 no cache 卻還是發請求,為什麼多次訪問時有時請求裡帶了 etag,有時又沒有帶?等等。後來查了一些資料以及同事親自驗證,總算對這些問題有了個清晰的理解,現在整理出來以...
瀏覽器快取機制
當我們瀏覽乙個頁面發現有異常時,通常考慮的就是書不是瀏覽器做了快取呢,按ctrl f5重新請求一次就能請求到沒有快取的頁面,這個是為什麼呢。首先,ctrl f5組合鍵重新整理頁面,那麼瀏覽器會直接向目標url傳送請求,而不再使用瀏覽器快取的資料。其次,當請求到達伺服器端依然有可能出現使用伺服器端的資...