瀏覽器快取就是把乙個已經請求過的web資源(如html頁面,,js,資料等)拷貝乙份副本儲存在瀏覽器中。快取會根據進來的請求儲存輸出內容的副本。當下乙個請求來到的時候,如果是相同的url,快取會根據快取機制決定是直接使用副本響應訪問請求,還是向源伺服器再次傳送請求。
(1)減少網路頻寬消耗
當web快取副本被使用時,只會產生極小的網路流量,可以有效的降低運營成本。
(2)降低伺服器壓力
給網路資源設定有效期之後,使用者可以重複使用本地的快取,減少對源伺服器的請求,間接降低伺服器的壓力。同時,搜尋引擎的爬蟲機械人也能根據過期機制降低爬取的頻率,也能有效降低伺服器的壓力。
(3)減少網路延遲,加快頁面開啟速度
對於終端使用者,快取的使用能夠明顯加快頁面開啟速度,達到更好的體驗。
強制快取(持久快取):
使用者傳送的請求,直接從客戶端快取中獲取,不傳送請求到伺服器,不與伺服器發生互動行為。
協商快取:
使用者傳送的請求,傳送到伺服器後,由伺服器判定是否從快取中獲取資源。
兩者共同點:客戶端獲得的資料最後都是從客戶端快取中獲得。
兩者的區別:從名字就可以看出,強快取不與伺服器互動,而協商快取則需要與伺服器互動。
強制快取優先於協商快取進行,若強制快取(expires和cache-control)生效則直接使用快取,若不生效則進行協商快取(last-modified / if-modified-since和etag / if-none-match),協商快取由伺服器決定是否使用快取,若協商快取失效,那麼代表該請求的快取失效,返回200,重新返回資源和快取標識,再存入瀏覽器快取中;生效則返回304,繼續使用快取。具體流程圖如下:
(a)瀏覽器判定是否有快取
瀏覽器怎麼判定是否有快取,就可以轉化為瀏覽器去讀取本地放快取的地方(注:不同瀏覽器不同系統都會不同)是否有該對應的請求啦。
總結來說就是個查詢檔案是否存在的問題。
(b)快取是否過期
我們再以這張圖為例,這張圖中表明,客戶端保留了乙個伺服器端的response header。
裡面的date欄位表明此次快取時伺服器的時間。
裡面有兩個字段:expires 、cache-control
expires
http1.0 中的標準,表明過期時間,注意此處的時間都是指的是伺服器的時間。
可以看到過期時間被設定為了:thu, 28 sep 2017 06:38:37 gmt
存在的問題:伺服器時間與客戶端時間的不一致,就會導致快取跟期待效果出現偏差。
cache-control
http1.1 中的標準,可以看成是 expires 的補充。使用的是相對時間的概念。
簡單介紹下cache-control的屬性設定。
1)max-age: 設定快取的最大的有效時間,單位為秒(s)。max-age會覆蓋掉expires
2) s-maxage: 只用於共享快取,比如cdn快取(s -> share)。與max-age 的區別是:max-age用於普通快取,
而s-maxage用於**快取。如果存在s-maxage,則會覆蓋max-age 和 expires.
3) public:響應會被快取,並且在多使用者間共享。預設是public。
4) private: 響應只作為私有的快取,不能在使用者間共享。如果要求http認證,響應會自動設定為private。
5)no-cache: 指定不快取響應,表明資源不進行快取。但是設定了no-cache之後並不代表瀏覽器不快取,而是在快取前要向伺服器確認資源是否被更改。因此有的時候只設定no-cache防止快取還是不夠保險,還可以加上private指令,將過期時間設為過去的時間。
6)no-store: 絕對禁止快取。
7)must-revalidate: 如果頁面過期,則去伺服器進行獲取。
設定cache-control 的規則可以參見下圖:
所以判斷快取是否過期步驟是:
1) 檢視是否有cache-control 的max-age / s-maxage , 如果有,則用伺服器時間date值 + max-age/s-maxage 的秒數計算出新的過期時間,將當前時間與過期時間進行比較,判斷是否過期
2)檢視是否有cache-control 的max-age / s-maxage,則用expires 作為過期時間比較
總結:(b)過程執行完後,如果判定為未過期,則使用客戶端快取。那麼就是屬於「強快取」。
(c)跟伺服器協商是否使用快取
到這一步的時候,瀏覽器會向伺服器傳送請求,同時如果上一次的快取中有last-modified 和 etag 字段,
瀏覽器將在request header 中加入if-modified-since(對應於last-modified), 和if-none-match(對應於etag)。
last-modified: 表明請求的資源上次的修改時間。
if-modified-since:客戶端保留的資源上次的修改時間。
etag:資源的內容標識。(不唯一,通常為檔案的md5或者一段hash值,只要保證寫入和驗證時的方法一致即可)
if-none-match: 客戶端保留的資源內容標識。
注:1) 分布式系統盡量關閉etag,因為每台機器生成的etag都不一樣。
2)分布式系統裡多台機器間檔案的last-modified必須一致,以免負載均衡不同導致對比失敗。
通常情況下,如果同時傳送 if-none-match 、if-modified-since欄位,伺服器只要比較etag 的內容即可,當然具體處理方式,看伺服器的約定規則。
(d)協商快取
在這個階段,伺服器一般會將cache-control、expires 、last-modified、date、etag 等字段在response header 中返回,便於下次快取。當然具體的場景,也是看伺服器的約定規則設定。
當然並不是所有請求都能被快取,無法被瀏覽器快取的請求如下:
1. http資訊頭中包含cache-control:no-cache,pragma:no-cache(http1.0),或cache-control:max-age=0等告訴瀏覽器不用快取的請求
2. 需要根據cookie,認證資訊等決定輸入內容的動態請求是不能被快取的
3. 經過https安全加密的請求(有人也經過測試發現,ie其實在頭部加入cache-control:max-age資訊,firefox在頭部加入cache-control:public之後,能夠對https的資源進行快取,參考《https的七個誤解》)
4. post請求無法被快取
5. http響應頭中不包含last-modified/etag,也不包含cache-control/expires的請求無法被快取
如果資源已經被瀏覽器快取下來,在快取失效之前,再次請求時,缺省會先檢查是否命中強快取,如果強快取命中則直接讀取快取,如果強快取沒有命中則發請求到伺服器檢查是否命中協商快取,如果協商快取命中,則告訴瀏覽器還是可以從快取讀取,否則才從伺服器返回最新的資源。這是預設的處理方式,這個方式可能被瀏覽器的行為改變:
(1)位址列訪問,鏈結跳轉是正常使用者行為,將會觸發瀏覽器快取機制;
(2)f5重新整理,瀏覽器會設定max-age=0,跳過強快取判斷,會進行協商快取判斷;
(3)ctrl+f5重新整理,跳過強快取和協商快取,直接從伺服器拉取資源。
瀏覽器快取機制
最近在準備優化日誌請求時遇到了一些令人疑惑的問題,比如為什麼響應頭里出現了兩個 cache control 為什麼明明設定了 no cache 卻還是發請求,為什麼多次訪問時有時請求裡帶了 etag,有時又沒有帶?等等。後來查了一些資料以及同事親自驗證,總算對這些問題有了個清晰的理解,現在整理出來以...
瀏覽器快取機制
當我們瀏覽乙個頁面發現有異常時,通常考慮的就是書不是瀏覽器做了快取呢,按ctrl f5重新請求一次就能請求到沒有快取的頁面,這個是為什麼呢。首先,ctrl f5組合鍵重新整理頁面,那麼瀏覽器會直接向目標url傳送請求,而不再使用瀏覽器快取的資料。其次,當請求到達伺服器端依然有可能出現使用伺服器端的資...
瀏覽器快取機制
瀏覽器快取機制 瀏覽器快取機制,其實主要就是 協議定義的快取機制 如 expires cache control 等 但是也有非 協議定義的快取機制,如使用 html meta 標籤,web 開發者可以在 html 頁面的節點中加入 標籤,如下 上述 的作用是告訴瀏覽器當前頁面不被快取,每次訪問都需...