url輸入後的整個流程(4)-http快取/瀏覽器快取
當客戶端第一次請求資料時,此時瀏覽器不存在快取資料,需要向伺服器請求資源,伺服器在返回資源的同時返回快取策略,http狀態碼為200,快取策略存在於響應頭裡,快取策略主要有強制快取和協商(對比)快取,客戶端拿到後將資料和快取策略快取到瀏覽器。
強制快取
對於強制快取,伺服器響應頭會有2個欄位來表示,expires/cache-control。
- expire
expires是一個時間戳,代表資源過期時間。不過該欄位是http1.0的,現在瀏覽器預設使用http1.1,所以基本不用這個欄位了,而且過期時間是由伺服器生成的,與客戶端的時間可能存在誤差,現在使用cache-control代替 - cache-control
cache-control常見的取值有:
max-age:快取的內容將在多少時間後失效;
no-cache: 會快取,使用協商快取策略;
no-store:所以內容都不會快取,每次請求都從伺服器獲取
瀏覽器第一次響應時將該欄位返回給客戶端,客戶端第二次請求時,根據該欄位的取值來決策,如果沒有超過max-age的過期時間,則直接從瀏覽器快取中取資料,狀態碼為200,如果超過過期時間或者有no-cache欄位,則走協商快取,如果有no-store欄位則直接從伺服器獲取。
協商快取
協商快取是進行比較後決定是否從伺服器獲取資源。協商快取的標識欄位有Last-Modified/Etag(響應頭裡),If-Modified-Since/If-None-Match(請求頭裡),這4個值之間是兩兩對應。
- Last-Modified/If-Modified-Since:
伺服器返回的Last-Modified指資源上次被修改的時間,伺服器第一次響應時將修改時間放入該欄位中,客戶端在第二次請求時,會將該值存入到If-Modified-Since欄位中傳送給伺服器,伺服器根據該欄位的取值來判斷資源是否被修改過,例如,伺服器第一次響應時資源修改的時間是當天下午3點,客戶端在下午5點第二次請求時,告訴伺服器我快取的資料的修改時間是下午3點,伺服器判斷請求的資源是否在3點到5點之間被修改過,如果沒有,則返回304狀態碼,客戶端使用本地快取,如果修改過則返回狀態碼200和新的資料。 - Etag/If-None-Match Etag是伺服器端生成的,當前請求資源的唯一識別符號,客戶端第二次請求時將該欄位快取在If-None-Match中傳送給伺服器,伺服器將此欄位與唯一識別符號對比,如果不相同則資源被修改過,返回新的資源,狀態碼為200,如果相同則返回狀態碼304,從快取中取。
- 為什麼要設定兩個欄位Last-Modified和Etag?
資源修改時間是伺服器端生成的,單位是s,如果一個資源在1s內被修改了n次,Last-Modified就會不夠精準出現誤差。 Etag和Last-Modified同時出現時,Etag的優先順序更高。
總結:
第一次請求時:

第二次請求時:

快取位置
討論快取策略的時候總是說從瀏覽器快取中取資料,那快取資料究竟存放在哪裡?一度我還以為是存放在cookie中,就沒搞清楚cookie和cache的區別,捂臉。
快取主要是對靜態資源而言,如圖片視訊等,我們可以在 Chrome 的開發者工具中,Network -> Size 一列看到一個請求最終的處理方式:如果是大小 (多少 K, 多少 M 等) 就表示是網路請求,否則會列出 from memory cache, from disk cache 和 from ServiceWorker
。
它們的優先順序是:(由上到下尋找,找到即返回;找不到則繼續)Service Worker、Memory Cache、硬碟 Cache、網路請求
- memory cache
記憶體中的快取。按照作業系統的常理:先讀記憶體,再讀硬碟。幾乎所有的網路請求資源都會被瀏覽器自動加入到 memory cache 中。但是也正因為數量很大但是瀏覽器佔用的記憶體不能無限擴大這樣兩個因素,memory cache 註定只能是個“短期儲存”。常規情況下,瀏覽器的 TAB 關閉後該次瀏覽的 memory cache 便告失效 (為了給其他 TAB 騰出位置)。而如果極端情況下 (例如一個頁面的快取就佔用了超級多的記憶體),那可能在 TAB 沒關閉之前,排在前面的快取就已經失效了。 - disk cache
也叫 HTTP cache,顧名思義是儲存在硬碟上的快取,因此它是持久儲存的,是實際存在於檔案系統中的。而且它允許相同的資源在跨會話,甚至跨站點的情況下使用,例如兩個站點都使用了同一張圖片。disk cache 會嚴格根據 HTTP頭資訊中的各類欄位來判定哪些資源可以快取,哪些資源不可以快取;哪些資源是仍然可用的,哪些資源是過時需要重新請求的。當命中快取之後,瀏覽器會從硬碟中讀取資源,雖然比起從記憶體中讀取慢了一些,但比起網路請求還是快了不少的。絕大部分的快取都來自 disk cache。 - Service Worker
上述的快取策略以及快取/讀取/失效的動作都是由瀏覽器內部判斷進行的, 我們只能設定響應頭的某些欄位來告訴瀏覽器,而不能自己操作。