http緩存機制與原理

1、瀏覽器緩存分類:強制緩存和協商緩存html

 

2、瀏覽器加載一個頁面的簡單流程node

瀏覽器第一次請求瀏覽器

 

 瀏覽器再次請求頁面緩存

 

 

 

 

3、http緩存涉及到的相關術語服務器

  • 緩存命中率:從緩存中獲得數據的請求數與全部請求數的比率。理想狀態是越高越好。
  • 過時內容:超過設置的有效時間,被標記爲「陳舊」的內容。一般過時內容不能用於回覆客戶端的請求,必須從新向源服務器請求新的內容或者驗證緩存的內容是否仍然準備。
  • 驗證:驗證緩存中的過時內容是否仍然有效,驗證經過的話刷新過時時間。
  • 失效:失效就是把內容從緩存中移除。當內容發生改變時就必須移除失效的內容。

 

4、強緩存函數

1.強緩存的過程工具

強緩存緊密聯繫着一個緩存時間期限,當瀏覽器請求資源的時候會查看緩存中的資源是否存在而且肯定該緩存的資源是否過了「保質期」,若沒有超過保質期則將取得緩存中的資源進行下一步處理。在Chrome的開發者工具中看到http的返回碼是200,可是在Size列會顯示爲(from cache)。url

 

圖解:spa

 

2.強緩存涉及到的相關參數操作系統

與強緩存相關的HTTP header 的字段有兩個 Expires以及Cache-Control

 Expires

緩存過時時間,用來指定資源到期的時間,是服務器端的具體的時間點。也就是說,Expires=max-age + 請求時間,須要和Last-modified結合使用。Expires是Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過時時間前瀏覽器能夠直接從瀏覽器緩存取數據,而無需再次請求。

 

該字段會返回一個時間,好比Expires:Thu,31 Dec 2037 23:59:59 GMT。這個時間表明着這個資源的失效時間,也就是說在2037年12月31日23點59分59秒以前都是有效的,即命中緩存。這種方式有一個明顯的缺點,因爲失效時間是一個絕對時間,因此當客戶端本地時間被修改之後,服務器與客戶端時間誤差變大之後,就會致使緩存混亂。因而發展出了Cache-Control。

Cache-Control

Cache-Control是一個相對時間,例如Cache-Control:3600,表明着資源的有效期是3600秒。因爲是相對時間,而且都是與客戶端時間比較,因此服務器與客戶端時間誤差也不會致使問題。
Cache-Control與Expires能夠在服務端配置同時啓用或者啓用任意一個,同時啓用的時候Cache-Control優先級高。

Cache-Control 能夠由多個字段組合而成,主要有如下幾個取值:

a.max-age 指定一個時間長度,在這個時間段內緩存是有效的,單位是s。例如設置 Cache-Control:max-age=31536000,也就是說緩存有效期爲(31536000 / 24 / 60 * 60)天,第一次訪問這個資源的時候,服務器端也返回了 Expires 字段,而且過時時間是一年後。

在沒有禁用緩存而且沒有超過有效時間的狀況下,再次訪問這個資源就命中了緩存,不會向服務器請求資源而是直接從瀏覽器緩存中取。

b.s-maxage 同 max-age,覆蓋 max-age、Expires,但僅適用於共享緩存,在私有緩存中被忽略。

c.public 代表響應能夠被任何對象(發送請求的客戶端、代理服務器等等)緩存。

d.private 代表響應只能被單個用戶(多是操做系統用戶、瀏覽器用戶)緩存,是非共享的,不能被代理服務器緩存。

e.no-cache 強制全部緩存了該響應的用戶,在使用已緩存的數據前,發送帶驗證器的請求到服務器。不是字面意思上的不緩存。

f.no-store 禁止緩存,每次請求都要向服務器從新獲取數據。

g.must-revalidate指定若是頁面是過時的,則去服務器進行獲取。這個指令並不經常使用,就不作過多的討論了。

 

 五協商緩存

1.協商緩存的過程

若未命中強緩存,則瀏覽器會將請求發送至服務器。服務器根據http頭信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match來判斷是否命中協商緩存。若是命中,則http返回碼爲304,瀏覽器從緩存中加載資源。

 

強緩存和協商緩存是相輔相成而且能夠共同存在的,強緩存優先級較高,意味着請求一個資源時會先比較強緩存的字段,若是命中則不會再執行接下來的協商緩存的過程。

 

 2.協商緩存涉及到的相關參數

a.Last-Modify/If-Modify-Since

瀏覽器第一次請求一個資源的時候,服務器返回的header中會加上Last-Modify,Last-modify是一個時間標識該資源的最後修改時間,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。

當瀏覽器再次請求該資源時,發送的請求頭中會包含If-Modify-Since,該值爲緩存以前返回的Last-Modify。服務器收到If-Modify-Since後,根據資源的最後修改時間判斷是否命中緩存。

若是命中緩存,則返回http304,而且不會返回資源內容,而且不會返回Last-Modify。因爲對比的服務端時間,因此客戶端與服務端時間差距不會致使問題。可是有時候經過最後修改時間來判斷資源是否修改仍是不太準確(資源變化了最後修改時間也能夠一致)。因而出現了ETag/If-None-Match。

 

 b.ETag/If-None-Match

 與Last-Modify/If-Modify-Since不一樣的是,Etag/If-None-Match返回的是一個校驗碼(ETag: entity tag)。ETag能夠保證每個資源是惟一的,資源變化都會致使ETag變化*。ETag值的變動則說明資源狀態已經被修改。服務器根據瀏覽器上發送的If-None-Match值來判斷是否命中緩存。

 

ETag擴展說明

咱們對ETag寄予厚望,但願它對於每個url生成惟一的值,資源變化時ETag也發生變化。神祕的Etag是如何生成的呢?以Apache爲例,ETag生成靠如下幾種因子:

<1>文件的i-node編號,此i-node非彼iNode。是Linux/Unix用來識別文件的編號。是的,識別文件用的不是文件名。使用命令’ls –I’能夠看到。

<2>文件最後修改時間

<3>文件大小
生成Etag的時候,可使用其中一種或幾種因子,使用抗碰撞散列函數來生成。因此,理論上ETag也是會重複的,只是機率小到能夠忽略

 

既生Last-Modified何生Etag?

你可能會以爲使用Last-Modified已經足以讓瀏覽器知道本地的緩存副本是否足夠新,爲何還須要Etag(實體標識)呢?HTTP1.1中Etag的出現主要是爲了解決幾個Last-Modified比較難解決的問題:

1. Last-Modified標註的最後修改只能精確到秒級,若是某些文件在1秒鐘之內,被修改屢次的話,它將不能準確標註文件的修改時間

2. 若是某些文件會被按期生成,當有時內容並無任何變化,但Last-Modified卻改變了,致使文件無法使用緩存

3.有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形

Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的惟一標識符,可以更加準確的控制緩存。Last-Modified與ETag是能夠一塊兒使用的,服務器會優先驗證ETag,一致的狀況下,纔會繼續比對Last-Modified,最後才決定是否返回304。

 

 六用戶行爲與緩存

瀏覽器緩存行爲還有用戶的行爲有關

 

 

參考博客

https://www.jianshu.com/p/f080181021cb

https://www.cnblogs.com/ranyonsue/p/8918908.html

相關文章
相關標籤/搜索