HTTP----HTTP快取機制

1oneLee發表於2020-12-23

前言

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

  • 快取的規則
  • 快取的方案
  • 快取的優點
  • 不同重新整理的請求執行過程

快取的規則

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

強制快取

當快取資料庫中已有所請求的資料時。客戶端直接從快取資料庫中獲取資料。當快取資料庫中沒有所請求的資料時,客戶端的才會從服務端獲取資料。

協商快取

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

小貼士:

兩類快取機制可以同時存在,強制快取的優先順序高於協商快取,當執行強制快取時,如若快取命中,則直接使用快取資料庫資料,不在進行快取協商。

快取的方案

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


接下來我們將對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
    告訴瀏覽器,你先把你快取中的這個檔案給我刪了,然後再去伺服器請求個完整的資原始檔下來。於是客戶端就完成了強行更新的操作.

相關文章