HTTP緩存機制有時候就是這麼簡單,4步即可理解

前言

緩存機制無處不在,有客戶端緩存,服務端緩存,代理服務器緩存等。在HTTP中具有緩存功能的是瀏覽器緩存。 HTTP緩存作為web性能優化的重要手段,對於從事web開發的朋友有重要的意義。本文將圍繞以下幾個方面來整理HTTP緩存:

  • 緩存的規則
  • 緩存的方案
  • 緩存的優點
  • 不同刷新的請求執行過程

緩存的規則

我們知道HTTP的緩存屬於客戶端緩存,後面會提到為什麼屬於客戶端緩存。所以我們認為瀏覽器存在一個緩存數據庫,用於儲存一些不經常變化的靜態文件(圖片、css、js等)。我們將緩存分為強制緩存和協商緩存。下面我將分別詳細的介紹這兩種緩存的緩存規則。

強制緩存

當緩存數據庫中已有所請求的數據時。客戶端直接從緩存數據庫中獲取數據。當緩存數據庫中沒有所請求的數據時,客戶端的才會從服務端獲取數據。

HTTP緩存機制有時候就是這麼簡單,4步即可理解

協商緩存

又稱對比緩存,客戶端會先從緩存數據庫中獲取到一個緩存數據的標識,得到標識後請求服務端驗證是否失效(新鮮),如果沒有失效服務端會返回304,此時客戶端直接從緩存中獲取所請求的數據,如果標識失效,服務端會返回更新後的數據。

HTTP緩存機制有時候就是這麼簡單,4步即可理解

小貼士:

兩類緩存機制可以同時存在,強制緩存的優先級高於協商緩存,當執行強制緩存時,如若緩存命中,則直接使用緩存數據庫數據,不在進行緩存協商。

緩存的方案

上面的內容讓我們大概瞭解了緩存機制是怎樣運行的,但是,服務器是如何判斷緩存是否失效呢?我們知道瀏覽器和服務器進行交互的時候會發送一些請求數據和響應數據,我們稱之為HTTP報文。報文中包含首部header和主體部分body。與緩存相關的規則信息就包含在header中。boby中的內容是HTTP請求真正要傳輸的部分。舉個HTTP報文header部分的例子如下:

HTTP緩存機制有時候就是這麼簡單,4步即可理解

接下來我們將對HTTP報文中出現的與緩存規則相關的信息做出詳細解釋。(我們依舊分為強制緩存和協商緩存兩個方面來介紹)

強制緩存

對於強制緩存,服務器響應的header中會用兩個字段來表明——Expires和Cache-Control。

Expires

Exprires的值為服務端返回的數據到期時間。當再次請求時的請求時間小於返回的此時間,則直接使用緩存數據。但由於服務端時間和客戶端時間可能有誤差,這也將導致緩存命中的誤差,另一方面,Expires是HTTP1.0的產物,故現在大多數使用Cache-Control替代。

Cache-Control

Cache-Control有很多屬性,不同的屬性代表的意義也不同。 private:客戶端可以緩存 public:客戶端和代理服務器都可以緩存 max-age=t:緩存內容將在t秒後失效 no-cache:需要使用協商緩存來驗證緩存數據 no-store:所有內容都不會緩存。

協商緩存

協商緩存需要進行對比判斷是否可以使用緩存。瀏覽器第一次請求數據時,服務器會將緩存標識與數據一起響應給客戶端,客戶端將它們備份至緩存中。再次請求時,客戶端會將緩存中的標識發送給服務器,服務器根據此標識判斷。若未失效,返回304狀態碼,瀏覽器拿到此狀態碼就可以直接使用緩存數據了。 對於協商緩存來說,緩存標識我們需要著重理解一下,下面我們將著重介紹它的兩種緩存方案。

Last-Modified

Last-Modified: 服務器在響應請求時,會告訴瀏覽器資源的最後修改時間。

if-Modified-Since: 瀏覽器再次請求服務器的時候,請求頭會包含此字段,後面跟著在緩存中獲得的最後修改時間。服務端收到此請求頭髮現有if-Modified-Since,則與被請求資源的最後修改時間進行對比,如果一致則返回304和響應報文頭,瀏覽器只需要從緩存中獲取信息即可。 從字面上看,就是說:從某個時間節點算起,是否文件被修改了

  1. 如果真的被修改:那麼開始傳輸響應一個整體,服務器返回:200 OK
  2. 如果沒有被修改:那麼只需傳輸響應header,服務器返回:304 Not Modified

if-Unmodified-Since: 從字面上看, 就是說: 從某個時間點算起, 是否文件沒有被修改

  1. 如果沒有被修改:則開始`繼續'傳送文件: 服務器返回: 200 OK
  2. 如果文件被修改:則不傳輸,服務器返回: 412 Precondition failed (預處理錯誤)

這兩個的區別是一個是修改了才下載一個是沒修改才下載。 Last-Modified 說好卻也不是特別好,因為如果在服務器上,一個資源被修改了,但其實際內容根本沒發生改變,會因為Last-Modified時間匹配不上而返回了整個實體給客戶端(即使客戶端緩存裡有個一模一樣的資源)。為了解決這個問題,HTTP1.1推出了Etag。

Etag

Etag: 服務器響應請求時,通過此字段告訴瀏覽器當前資源在服務器生成的唯一標識(生成規則由服務器決定)

If-None-Match: 再次請求服務器時,瀏覽器的請求報文頭部會包含此字段,後面的值為在緩存中獲取的標識。服務器接收到次報文後發現If-None-Match則與被請求資源的唯一標識進行對比。

  1. 不同,說明資源被改動過,則響應整個資源內容,返回狀態碼200。
  2. 相同,說明資源無心修改,則響應header,瀏覽器直接從緩存中獲取數據信息。返回狀態碼304.

但是實際應用中由於Etag的計算是使用算法來得出的,而算法會佔用服務端計算的資源,所有服務端的資源都是寶貴的,所以就很少使用Etag了。

緩存的優點

  1. 減少了冗餘的數據傳遞,節省寬帶流量
  2. 減少了服務器的負擔,大大提高了網站性能
  3. 加快了客戶端加載網頁的速度 這也正是HTTP緩存屬於客戶端緩存的原因。

不同刷新的請求執行過程

  1. 瀏覽器地址欄中寫入URL,回車 瀏覽器發現緩存中有這個文件了,不用繼續請求了,直接去緩存拿。(最快)
  2. F5 F5就是告訴瀏覽器,別偷懶,好歹去服務器看看這個文件是否有過期了。於是瀏覽器就膽膽襟襟的發送一個請求帶上If-Modify-since。
  3. Ctrl+F5 告訴瀏覽器,你先把你緩存中的這個文件給我刪了,然後再去服務器請求個完整的資源文件下來。於是客戶端就完成了強行更新的操作.


分享到:


相關文章: