以前專案中遇到了很多瀏覽器快取相關的問題,也在網上查過資料,搞過伺服器的配置,來確保客戶端載入伺服器資源的速度和資源有效性。最近仔細看了下http協議中和快取相關的一些屬性,總結一下。
瀏覽器快取原理
文字版描述
①瀏覽器第一次訪問伺服器資源 /index.html
在瀏覽器中沒有快取檔案,直接向伺服器傳送請求。
伺服器返回 200 OK,實體中返回 index.html檔案內容,並設定一個快取過期時間,一個檔案修改時間,一個根據index.html內容計算出來的實體標記Entity Tag,簡稱Etag。
瀏覽器將/index.html路徑的請求快取到本地。
②瀏覽器第二次訪問伺服器資源 /index.html
由於本地已經有了此路徑下的快取檔案,所以這一次就不直接向伺服器傳送請求了。
首先,進行快取過期判斷。瀏覽器根據①中設定快取過期時間判斷快取檔案是否過期。
情景一:若沒有過期,則不向伺服器傳送請求,直接使用快取中的結果,此時我們在瀏覽器控制檯中可以看到 200 OK(from cache) ,此時的情況就是完全使用快取,瀏覽器和伺服器沒有任何互動的。
情景二:若已過期,則向伺服器傳送請求,此時請求中會帶上①中設定的檔案修改時間,和Etag
然後,進行資源更新判斷。伺服器根據瀏覽器傳過來的檔案修改時間,判斷自瀏覽器上一次請求之後,檔案是不是沒有被修改過;根據Etag,判斷檔案內容自上一次請求之後,有沒有發生變化
情形一:若兩種判斷的結論都是檔案沒有被修改過,則伺服器就不給瀏覽器發index.html的內容了,直接告訴它,檔案沒有被修改過,你用你那邊的快取吧—— 304 Not Modified,此時瀏覽器就會從本地快取中獲取index.html的內容。此時的情況叫協議快取,瀏覽器和伺服器之間有一次請求互動。
情形二:若修改時間和檔案內容判斷有任意一個沒有通過,則伺服器會受理此次請求,之後的操作同①
我的文字表達能力可能有限,為了儘量把這個流程描述清楚一點,下面
一圖以蔽之
快取相關首部欄位
request快取相關首部欄位
response快取相關首部欄位
實體首部快取相關欄位
response的head裡邊可能還包括實體首部,實體首部是緊跟在response首部後邊的。
①last-modified-time ——用來設定資源最後修改時間
②Exprire —— 設定檔案過期時間
這個欄位的作用和cache-control相同,不同的是它直接指定一個快取過期時間點,容易受客戶端時間的影響。
這也是一個遺留的欄位,和cache-control同時存在的時候會被後者覆蓋
快取配置的一些注意事項
① 只有get請求會被快取,post請求不會
② Etag 在資源分佈在多臺機器上時,對於同一個資源,不同伺服器生成的Etag可能不相同,此時就會導致304協議快取失效,客戶端還是直接從server取資源。可以自己修改伺服器端etag的生成方式,根據資源內容生成同樣的etag。
③ 系統上線,更新資源時,可以在資源uri後邊附上資源修改時間、svn版本號、檔案md5 等資訊,這樣可以避免使用者下載到快取的舊的檔案
④ 觀察chrome的表現發現,通過連結或者位址列訪問,會先判斷快取是否過期,再判斷緩資源是否更新;F5重新整理,會跳過快取過期判斷,直接請求伺服器,判斷資源是否更新。
目前只能回憶起這些了,以後遇到了再補充吧~