以前只知道返回的狀態碼是304說明上次請求的資源沒有被修改,可以直接訪問,增加訪問速度,但是當別人問304是怎麼來的時候,卻又不知道從何說起了。
所以今天就對於瀏覽器快取機制進行了比較全面的理解。
瀏覽器的快取機制就是將請求的內容儲存在了本地,不用每次請求相同的內容時都需要向伺服器傳送同樣的請求去獲取,這樣就大大的浪費了頻寬,增加了頁面的展現速度和增大了伺服器的壓力。
那麼什麼時候可以向伺服器傳送請求,什麼時候可以直接使用本地的快取的內容呢?
當使用者第一次訪問的時候,很顯然必須是要向伺服器端傳送請求獲取資源的,獲取資源之後一般會儲存到本地快取,當下次訪問同樣的資源時,就會進行一系列的比較,會確定到底是應該在本地快取中獲取還是向伺服器端獲取,那麼怎樣判斷呢?
瀏覽器會在第一次請求完伺服器後得到響應,我們可以在伺服器中設定這些響應,從而達到在以後的請求中儘量減少甚至不從伺服器獲取資源的目的。瀏覽器是依靠請求和響應中的的頭資訊來控制快取的。
先來看一下http響應頭中有關快取的字段資訊:
在這裡我們通過三方面來進行討論。
①. cache-control和expires(響應)
②. last-modified和if-modified-since(響應和請求)
③. etag和if-none-match(響應和請求)
一、首先來討論cache-control和expires
是伺服器端用來約定和客戶端的有效時間的。
二、 last-modified和if-modified-since(響應和請求)
這是當上面設定的伺服器端時間過期過後,檢查伺服器端檔案是否更新的一種方法。
last-modified(響應),標識響應資源的最後修改時間,web伺服器在響應資源時,告訴瀏覽器資源的最後修改時間。
if-modified-since(請求),需要配合cache-control一起使用。當快取資源過期後,也就是(cache-control:max-age = 0),假設該資源有last-modified宣告,則再次向伺服器請求時帶上頭 if-modified-since,表示請求時間。伺服器收到請求後發現有if-modified-since,則與被請求資源的最後修改時間進行對比。如果last-modified日期比較新,說明在請求的資源被修改過,或者說已經不是快取中的相同的資源錄入,所以http就會返回200。反之說明沒被修改,返回狀態碼304,告知瀏覽器繼續使用所儲存的快取資源,同時更新響應頭last-modified的值(以備下次對比)。
三、 etag和if-none-match(響應和請求)
是第二種方式檢測伺服器端檔案是否更新的一種方式,同樣需要配合cache-control使用。
響應頭中的etag(實體標籤)不是什麼版本號或者什麼,它是web伺服器(比如apache將檔案的索引節(inode),大小(size)和最後修改時間(mtime)進行hash後得到的。))標識檔案的唯一識別符號。
當快取資源過期後,瀏覽器發現伺服器端返回的頭部資訊中有etag資訊,就會在請求中加入if-none-match資訊(上一次請求後的響應頭的etag),該值在服務端和服務端代表該檔案唯一的字串對比(如果服務端該檔案改變了,該值就會變),如果相同,則響應http304,客戶端直接讀取快取,如果不相同,則響應http200,返回最新的資料資源,更新etag值。
etag的出現主要是為了解決last-modified的以下不足:
1。last-modified標註的最後修改只能精確到秒級,如果某些檔案在1秒鐘以內,被修改多次的話,它將不能準確標註檔案的修改時間。
2。如果某些檔案會被定期生成,但有時內容並沒有任何變化(僅僅改變了時間),但last-modified卻改變了,導致檔案沒法使用快取
3。有可能存在伺服器沒有準確獲取檔案修改時間,或者與**伺服器時間不一致等情形。
簡言之,就是當瀏覽器快取過期後,客戶端就會重新向伺服器端傳送請求,請求頭中帶有if-none-match(上一次請求後的響應etag)資訊,會在伺服器端進行匹配,與響應頭中的etag值相等,則沒有發生變化,反之發生了變化。
但當上圖同時存在if-none-match和if-modified-since時,前者優先。因為前者的出現就是為了解決後者的不足。
當然並不是所有請求都能,或者都被應該快取。
http資訊頭中包含cache-control:no-cache,pragma:no-cache,或cache-control:max-age=0等告訴瀏覽器不用快取的請求
需要根據cookie,認證資訊等決定輸入內容的動態請求是不能被快取的
經過https安全加密的請求(有人也經過測試發現,ie其實在頭部加入cache-control:max-age資訊,firefox在頭部加入cache-control:public之後,能夠對https的資源進行快取,參考《https的七個誤解》)
post請求無法被快取
http響應頭中不包含last-modified/etag,也不包含cache-control/expires的請求無法被快取。
所以接下來簡單的總結一下:
在第一次請求資源時,毫無疑問會向伺服器端傳送請求請求資源,當再次傳送請求時就會進行一系列的比較:
首先會檢查瀏覽器是否存在快取,有的話比較快取是否過期,沒有過期的話,直接讀取快取中的資訊,返回304。
如果快取過期了檢視響應頭中是否存在etag(實體標籤)資訊,有的話向伺服器端傳送帶有if-none-match(為上一次的etag值)的請求,對比兩個是否相等,相等的話伺服器端返回304,讀取快取。不相等的話返回200,更新快取和etag。
如果快取過期了並且響應頭中不存在etag資訊,則繼續檢查是否存在last-modified資訊,如果存在則在請求頭中附上帶if-modified-since(上次檔案修改的時間)的請求。判斷兩者是否相等,相等的話伺服器端返回304,讀取快取。不相等的話返回200,更新快取和last-modified。
若快取過期了,並且響應頭中不存在etag或者last-modified,則直接向伺服器傳送新的請求,等待請求響應,快取協商,呈現頁面。
以上就是自己對瀏覽器快取機制的理解,參照的是
瀏覽器快取機制
最近在準備優化日誌請求時遇到了一些令人疑惑的問題,比如為什麼響應頭里出現了兩個 cache control 為什麼明明設定了 no cache 卻還是發請求,為什麼多次訪問時有時請求裡帶了 etag,有時又沒有帶?等等。後來查了一些資料以及同事親自驗證,總算對這些問題有了個清晰的理解,現在整理出來以...
瀏覽器快取機制
當我們瀏覽乙個頁面發現有異常時,通常考慮的就是書不是瀏覽器做了快取呢,按ctrl f5重新請求一次就能請求到沒有快取的頁面,這個是為什麼呢。首先,ctrl f5組合鍵重新整理頁面,那麼瀏覽器會直接向目標url傳送請求,而不再使用瀏覽器快取的資料。其次,當請求到達伺服器端依然有可能出現使用伺服器端的資...
瀏覽器快取機制
瀏覽器快取機制 瀏覽器快取機制,其實主要就是 協議定義的快取機制 如 expires cache control 等 但是也有非 協議定義的快取機制,如使用 html meta 標籤,web 開發者可以在 html 頁面的節點中加入 標籤,如下 上述 的作用是告訴瀏覽器當前頁面不被快取,每次訪問都需...