在一次http請求過程當中,http緩存主要涉及到三個角色:瀏覽器、瀏覽器緩存和服務端。如下咱們按照一次http請求的順序,討論下不一樣狀況下緩存的表現。html
瀏覽器-瀏覽器緩存(強制緩存)
1. 瀏覽器是否有緩存?
安裝瀏覽器時,會生成一個存放緩存的文件夾。此文件夾中包含了各緩存資源和資源的相關信息(好比url、expire time等)。若是有此資源的緩存記錄,則表示有緩存;沒有則表示沒有緩存。
查看緩存文件的方法以下:chrome
mac下目錄:/Users/XXX/Library/Caches/Google/Chrome/Default/Cache
windows下目錄
C:\Users\{用戶名}\AppData\Local\Google\Chrome\User Data\Default\Cache
打開文件夾,能夠看到裏面保存着許多文件,這些都是緩存的資源,可是都是通過編碼的,且咱們不知道文件類型,所以沒法查看。windows下有個工具能夠幫忙查看。windows
![](http://static.javashuo.com/static/loading.gif)
裏面清晰的包含了每條緩存的相關信息(這些信息保存在cache文件夾下的index文件中),包括url、file size、expire time、cache control等。選中一條記錄,按F7能夠直接查看當前緩存資源、按F4能夠查看並保存當前緩存資源。瀏覽器
2. 瀏覽器緩存是否過時
若是請求的資源有緩存,則瀏覽器會判斷緩存是否過時,主要經過如下兩個字段:緩存
- expire:值爲一個絕對時間,表示資源過時的時間。若是當前時間大於此值,則表示已過時,反之未過時。expire是HTTP1.0標準下的字段。
- cache-control:HTTP1.1標準下的字段。
max-age:值爲一個單位爲毫秒的時間段,表示資源在***毫秒後過時
must-revalidate
經過以上判斷,若是緩存未過時,則直接採用緩存資源,並返回200(for cache);若緩存已過時,則要從新像服務端請求最新的資源。服務器
【expire和cache-control的關係】工具
- 若是請求中同時存在二者expire和cache-control:max-age,則expire將被忽略
- expire爲絕對時間,這一依賴於客戶端與服務端的時間保持一致,若客戶端時間出錯,將會判斷有誤;max-age爲相對時間,不會出現此問題
【no-cache與no-store】
no-cache與no-store在客戶端和服務端上表明的意義不同,要分開來講。編碼
- 在服務端響應中:no-cache表示瀏覽器能夠對資源進行緩存,可是每次使用資源時不能直接使用,必須從新請求(也就是採用西面講到的協商緩存);no-store不容許瀏覽器對資源進行緩存,也就是客戶端根本不會存在此資源的緩存文件。從上面的記錄中的cache-control也能看出來,只會出現no-cache,不會出現no-store,由於no-store的資源壓根不會被緩存,也就不會出如今緩存記錄中
- 在客戶端請求中:no-cache表示這次請求不採用緩存文件(即便有緩存),須要要服務端請求,返回200。(ctrl+F5強制刷新時,就是講cache-control設置爲no-cache)做用至關於服務端響應中的no-store
【客戶端no-cache和max-age=0】url
no-cache表示必須從新像服務端請求資源,返回200;max-age=0表示在從新獲取資源以前,先檢驗ETag/Last-Modified,返回304.net
瀏覽器-服務端(協商緩存)
當瀏覽器沒有緩存時,瀏覽器將像服務端發起請求。此時服務端也不直接返回新資源,會先看看客戶端的資源是否已是最新資源。
- 在上一次請求的響應中,服務端的response headers中會包含last-modified和etag(能夠在上面提到的緩存記錄中看到),當客戶端再次發起請求時,會在request headers中帶上 if-modified-since(對應last-modified的值)和if-none-match(對應etag的值)
- if-modified-since:服務端對比發過來的if-modifind-since和服務端的last-modified,若是時間一致,表示至上次請求後,服務端上此資源未修改過,瀏覽器可使用緩存中的數據。相應狀態碼304,
- if-none-match:服務端對比發過來的if-none-match和服務端的etag,若是相等,表示至上次請求後,服務端上此資源未修改過,瀏覽器可使用緩存中的數據。相應狀態碼304
【last-modified與etag的關係】
- last-modified只能精確到秒,若文件修改的一秒內修改屢次,last-modified沒法判斷
- 有些資源會週期性的更新,但內容不必定變(僅最後修改時間last-modified變化),此時咱們認爲此資源未被修改,而last-modified會發生變化,etag(通常此類週期性更新的資源,etag中不依賴最後修改時間)未發生變化
- 某些服務器不能精確的獲得文件的最後修改時間