寫給後端程式設計師的HTTP快取原理介紹
通過Internet獲取資源既緩慢,成本又高。為此,Http協議裡包含了控制快取的部分,以使Http客戶端可以快取和重用以前獲取的資源,從而優化效能,提升體驗。雖然Http中關於快取控制的部分,隨著協議演進,有一些變化。但我覺著,作為後端程式設計師,在開發Web服務時,只需要關注請求頭If-None-Match、響應頭ETag、響應頭Cache-Control就足夠了。因為這三個Http頭就可以滿足你的需求,並且,當今絕大多數的瀏覽器,都支援這三個Http頭。我們所要做的就是,確保每個伺服器響應都提供正確的 HTTP 頭指令,以指導瀏覽器何時可以快取響應以及可以快取多久。
快取在哪兒?
上圖中有三個角色,瀏覽器、Web代理和伺服器,如圖所示HTTP快取存在於瀏覽器和Web代理中。當然在伺服器內部,也存在著各種快取,但這已經不是本文要討論的Http快取了。所謂的Http快取控制,就是一種約定,通過設定不同的響應頭Cache-Control來控制瀏覽器和Web代理對快取的使用策略,通過設定請求頭If-None-Match和響應頭ETag,來對快取的有效性進行驗證。
響應頭ETag
ETag全稱Entity Tag,用來標識一個資源。在具體的實現中,ETag可以是資源的hash值,也可以是一個內部維護的版本號。但不管怎樣,ETag應該能反映出資源內容的變化,這是Http快取可以正常工作的基礎。
如上例中所展示的,伺服器在返回響應時,通常會在Http頭中包含一些關於響應的後設資料資訊,其中,ETag就是其中一個,本例中返回了值為x1323ddx的ETag。當資源/file的內容發生變化時,伺服器應當返回不同的ETag。
請求頭If-None-Match
對於同一個資源,比如上一例中的/file,在進行了一次請求之後,瀏覽器就已經有了/file的一個版本的內容,和這個版本的ETag,當下次使用者再需要這個資源,瀏覽器再次向伺服器請求的時候,可以利用請求頭If-None-Match來告訴伺服器自己已經有個ETag為x1323ddx的/file,這樣,如果伺服器上的/file沒有變化,也就是說伺服器上的/file的ETag也是x1323ddx的話,伺服器就不會再返回/file的內容,而是返回一個304的響應,告訴瀏覽器該資源沒有變化,快取有效。
如上例中所示,在使用了If-None-Match之後,伺服器只需要很小的響應就可以達到相同的結果,從而優化了效能。
響應頭Cache-Control
每個資源都可以通過Http頭Cache-Control來定義自己的快取策略,Cache-Control控制誰在什麼條件下可以快取響應以及可以快取多久。 最快的請求是不必與伺服器進行通訊的請求:通過響應的本地副本,我們可以避免所有的網路延遲以及資料傳輸的資料成本。為此,HTTP 規範允許伺服器返回一系列不同的 Cache-Control 指令,控制瀏覽器或者其他中繼快取如何快取某個響應以及快取多長時間。
Cache-Control 頭在 HTTP/1.1 規範中定義,取代了之前用來定義響應快取策略的頭(例如 Expires)。當前的所有瀏覽器都支援 Cache-Control,因此,使用它就夠了。
以下我來介紹可以再Cache-Control中設定的常用指令。
max-age
該指令指定從當前請求開始,允許獲取的響應被重用的最長時間(單位為秒。例如:Cache-Control:max-age=60表示響應可以再快取和重用 60 秒。需要注意的是,在max-age指定的時間之內,瀏覽器不會向伺服器傳送任何請求,包括驗證快取是否有效的請求,也就是說,如果在這段時間之內,伺服器上的資源發生了變化,那麼瀏覽器將不能得到通知,而使用老版本的資源。所以在設定快取時間的長度時,需要慎重。
public和private
如果設定了public,表示該響應可以再瀏覽器或者任何中繼的Web代理中快取,public是預設值,即Cache-Control:max-age=60等同於Cache-Control:public, max-age=60。
在伺服器設定了private比如Cache-Control:private, max-age=60的情況下,表示只有使用者的瀏覽器可以快取private響應,不允許任何中繼Web代理對其進行快取 – 例如,使用者瀏覽器可以快取包含使用者私人資訊的 HTML 網頁,但是 CDN 不能快取。
no-cache
如果伺服器在響應中設定了no-cache即Cache-Control:no-cache,那麼瀏覽器在使用快取的資源之前,必須先與伺服器確認返回的響應是否被更改,如果資源未被更改,可以避免下載。這個驗證之前的響應是否被修改,就是通過上面介紹的請求頭If-None-match和響應頭ETag來實現的。
需要注意的是,no-cache這個名字有一點誤導。設定了no-cache之後,並不是說瀏覽器就不再快取資料,只是瀏覽器在使用快取資料時,需要先確認一下資料是否還跟伺服器保持一致。如果設定了no-cache,而ETag的實現沒有反應出資源的變化,那就會導致瀏覽器的快取資料一直得不到更新的情況。
no-store
如果伺服器在響應中設定了no-store即Cache-Control:no-store,那麼瀏覽器和任何中繼的Web代理,都不會儲存這次相應的資料。當下次請求該資源時,瀏覽器只能重新請求伺服器,重新從伺服器讀取資源。
怎樣決定一個資源的Cache-Control策略呢?
下面這個流程圖,可以幫到你。
相關文章
- 寫給程式設計師的 Unicode 入門介紹程式設計師Unicode
- 寫給 Python 程式設計師看的 Rust 介紹Python程式設計師Rust
- phpob快取原理介紹PHP快取
- 程式設計師給小孩取的名字程式設計師
- 給後端程式設計師看的 Vue 快速入門教程後端程式設計師Vue
- 某資深程式設計師寫給後來者的忠告程式設計師
- 寫給程式設計師:當自己的上帝程式設計師
- 如何向新手程式設計師介紹程式設計?程式設計師
- 後端程式設計師寫前端用什麼框架好後端程式設計師前端框架
- 一個老程式設計師的程式設計之路,寫給年輕的程式設計師們程式設計師
- 寫給前端程式設計師的命令列入門前端程式設計師命令列
- 寫給新入行的程式設計師小朋友程式設計師
- 寫給程式設計師的有效學習方法程式設計師
- 寫給未來程式設計師的建議程式設計師
- redis快取介紹Redis快取
- 《C++ API 設計》——寫給想寫好類庫的程式設計師C++API程式設計師
- HTTP快取機制及原理HTTP快取
- http快取機制及其原理HTTP快取
- 寫給前端程式設計師的英文學習指南前端程式設計師
- 不要問程式設計師什麼是“物件”,也不要給他介紹“物件”程式設計師物件
- 函式程式設計基本原理介紹函式程式設計
- 設計師,寫給CEO,寫給產品,寫給運營,寫給技術
- Caffeine快取的簡單介紹快取
- 幽默:全棧程式設計師與前後端程式設計師區別全棧程式設計師後端
- 寫給Java程式設計師的Java虛擬機器學習指南Java程式設計師虛擬機機器學習
- 寫給程式設計師的管理入門課程(轉)程式設計師
- 寫給考慮創業的年輕程式設計師創業程式設計師
- 寫給iOS程式設計師的命令列使用祕籍iOS程式設計師命令列
- 瀏覽器HTTP快取原理分析瀏覽器HTTP快取
- 《程式設計師健康指南》:給程式設計師的健康書程式設計師
- 寫給後端的Nginx初級入門教程:Nginx原理初探後端Nginx
- 給程式設計師的幾點程式設計經驗----《編寫高質量程式碼》程式設計師
- 好程式設計師Java培訓分享本地快取如何設計程式設計師Java快取
- 寫給Java程式設計師學習路線圖Java程式設計師
- 送給程式設計師:最好的程式設計名言程式設計師
- 程式設計中快取的使用程式設計快取
- 快取融合(Cache Fusion)介紹快取
- MyBatis中的一級快取和二級快取介紹MyBatis快取