瀏覽器HTTP緩存原理分析

之前項目中遇到了不少瀏覽器緩存相關的問題,也在網上查過資料,搞過服務器的配置,來確保客戶端加載服務器資源的速度和資源有效性。最近仔細看了下http協議中和緩存相關的一些屬性,總結一下。html

瀏覽器緩存原理

文字版描述

①瀏覽器第一次訪問服務器資源 /index.htmlchrome

在瀏覽器中沒有緩存文件,直接向服務器發送請求。瀏覽器

服務器返回  200 OK,實體中返回 index.html文件內容,並設置一個緩存過時時間,一個文件修改時間,一個根據index.html內容計算出來的實體標記Entity Tag,簡稱Etag。緩存

瀏覽器將/index.html路徑的請求緩存到本地。服務器

 

②瀏覽器第二次訪問服務器資源 /index.htmlsvn

因爲本地已經有了此路徑下的緩存文件,因此這一次就不直接向服務器發送請求了。post

首先進行緩存過時判斷。瀏覽器根據①中設置緩存過時時間判斷緩存文件是否過時。spa

情景一:若沒有過時,則不向服務器發送請求,直接使用緩存中的結果,此時咱們在瀏覽器控制檯中能夠看到  200 OK(from cache) ,此時的狀況就是徹底使用緩存,瀏覽器和服務器沒有任何交互的。3d

情景二:若已過時,則向服務器發送請求,此時請求中會帶上①中設置的文件修改時間,和Etag代理

而後進行資源更新判斷。服務器根據瀏覽器傳過來的文件修改時間,判斷自瀏覽器上一次請求以後,文件是否是沒有被修改過;根據Etag,判斷文件內容自上一次請求以後,有沒有發生變化

情形一:若兩種判斷的結論都是文件沒有被修改過,則服務器就不給瀏覽器發index.html的內容了,直接告訴它,文件沒有被修改過,你用你那邊的緩存吧—— 304 Not Modified,此時瀏覽器就會從本地緩存中獲取index.html的內容。此時的狀況叫協議緩存,瀏覽器和服務器之間有一次請求交互。

情形二:若修改時間和文件內容判斷有任意一個沒有經過,則服務器會受理這次請求,以後的操做同①

 

個人文字表達能力可能有限,爲了儘可能把這個流程描述清楚一點,下面

一圖以蔽之

緩存相關首部字段

request緩存相關首部字段

① cache-control  用來作 緩存過時判斷
經常使用指令:
no-cache  不直接使用緩存,始終向服務器發起請求
max-age  緩存過時時間,是一個時間數值,好比3600秒,設置爲0的時候效果等同於no-cache
s-maxage  給緩存代理用的指令,對直接返回資源的server無效,當s-maxage生效時,會忽略max-age的值
only-if-cached 如有緩存,則只使用緩存,若緩存文件出問題了,請求也會出問題
② Pragma   用來作緩存過時判斷
   它能夠取值no-cache
   這是一個http1.0遺留的字段,當它和cache-control同時存在的時候,會被cache-control覆蓋
③ if-match / if-none-match  用來作 資源更新判斷
   這個指令會把緩存中的Etag傳給服務器,服務器用它來和服務器端的資源Etag進行對比,若不一致則證實資源被修改了,須要響應請求爲 200 OK
④ if-modified-since  用來作資源更新判斷
    這個指令會把文件的上一次緩存中的文件的更新時間傳給服務器,服務器判斷文件在這個時間點後是否被修改,若是被修改過則須要響應請求爲200 OK

response緩存相關首部字段

① cache-control  用來設置緩存過時時間
經常使用指令:
no-cache  讓客戶端不直接使用緩存,始終向服務器發起請求,不設置默認是這個,上邊截圖中的請求就是省略了,因此客戶端不會直接使用緩存。
max-age  緩存過時時間,是一個時間數值,好比3600秒,設置爲0的時候效果等同於no-cache
s-maxage  給緩存代理用的指令,對直接返回資源的server無效,當s-maxage生效時,會忽略max-age的值
private/public  默認是private,只在一個瀏覽器中緩存,設置爲public時緩存可被多個用戶共享
② Etag 用來 設置根據資源內容生成的實體標籤
    這個值有強tag和弱tag,區別是計算方式不一樣,只有強tag纔會在資源被更新的時候當即發生變化,請求首部中的if-match/if-none-match字段就會傳回這個值給服務端
③ age 
   這個字段用來告訴客戶端,這個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刷新,會跳過緩存過時判斷,直接請求服務器,判斷資源是否更新。

目前只能回憶起這些了,之後遇到了再補充吧~

相關文章
相關標籤/搜索