【轉載】掌握 HTTP 快取——從請求到響應過程的一切(上)
作者:Ulrich Kautz
編譯:鬍子大哈
翻譯原文:http://huziketang.com/blog/posts/detail?postId=58b77935204d50674934c3ad
英文原文:Mastering HTTP Caching - from request to response and everything
轉載請註明出處,保留原文連結以及作者資訊
學習筆記
HTPP 響應快取頭:
1、新版本指的是 HTTP/1.1
2、而舊版本指的是 HTTP/1.0
ETag:它是文件版本的識別符號
通常是內容的 MD5 值,不過它也可以包含其他內容,代表的是文件的版本/日期,如: 1.0 或者 2017-02-27。這裡注意一點是,它必須用雙引號括起來,如:ETag: "d3b07384d113edec49eaa6238ad5ff00"。
客戶端請求了http://doc.tinywan.com:8038/cache2.txt,接著服務端返回瞭如下的響應內容:
第一次訪問:
在響應裡面,有兩個有意思的頭標識:
【1】一個是 ETag,內容的 MD5值。
【2】一個是 Last-Modified,這是 cache2.txt 檔案最後一次被修改的時間。
這裡就是二次驗證起作用的地方:當客戶端在很短的時間內再次訪問上面的 URL,客戶端瀏覽器會使用 If-* 請求頭。如 If-None-Match 檢查 ETag 的內容是否有改變。也就是說,如果 ETag 發生變化,客戶端接收到的一個完整的新響應;如果 ETag 沒變化,客戶端接收到的是一個表明內容沒變化的標識。
第二次訪問:
正如上面所展示的,這次伺服器的響應裡面不是 200 ok,而是304 Not Modified,這就是說它略過包體部分,讓客戶端直接去自己的快取裡拿資料。
我們修改cache2.txt檔案
注意:以上紅線劃出來的地方,已經發生變化了
在處理上面那個cache2.txt 靜態檔案的例子時,客戶端還可以使用 If-Modified-Since:Sun, 24 Sep 2017 05:27:44 GMT 來達到同樣的效果(返回 304 響應)。這對於靜態檔案來說也很好用,因為響應頭中的 Last-Modified
ETag
頭是更好的選擇。
Cache-Control頭
Cache-Control 頭相對來講難一些。兩個原因:
第一,Cache-Control 既可以用於請求頭,也可以用於響應頭。本文中著重討論響應頭,因為這是開發者所必須要掌握的。
第二,它控制著兩個快取:本地快取(又稱私有快取)和共享快取。
本地快取,是指在客戶端本地機器中的快取。站在開發者的角度,它並不完全受你的控制,通常瀏覽器會自己決定是否把某些內容放到快取中,這意味著:不要依賴於本地快取。使用者也可能在關閉瀏覽器的時候清理所有快取,而你並不知道有這樣的操作。除非你監測到了某個使用者的流量不斷上漲,導致快取內容迅速失效,這時候你才會意識到。
共享快取,也就是本文所介紹的:處於客戶端和伺服器之間的快取。即 CDN。你對共享快取擁有絕對的控制,應該好好地利用它。
現在我們來用一些程式碼作為示例深入學習一下。
Cache-Control: public max-age=3600
Cache-Control: private immutable
Cache-Control: no-cache
Cache-Control: public max-age=3600 s-maxage=7200
Cache-Control: public max-age=3600 proxy-revalidate
首先是緩衝能力,它關注的是快取到什麼地方,和是否應該被快取。他的幾個重要的屬性是:
private
:表示它只應該存在本地快取;public
:表示它既可以存在共享快取,也可以被存在本地快取;no-cache
:表示不論是本地快取還是共享快取,在使用它以前必須用快取裡的值來重新驗證;no-store
:表示不允許被快取。
第二個是過期時間,很顯然它關注的是內容可以被快取多久。它的幾個重要的屬性是:
max-age=<seconds>
:設定快取時間,設定單位為秒。本地快取和共享快取都可以;s-maxage=<seconds>
:覆蓋max-age
屬性。只在共享快取中起作用。
最後一個是二次驗證,表示精細控制。它的幾個重要屬性是:
immutable
:表示文件是不能更改的。must-revalidate
:表示客戶端(瀏覽器)必須檢查代理伺服器上是否存在,即使它已經本地快取了也要檢查。proxy-revalidata
:表示共享快取(CDN)必須要檢查源是否存在,即使已經有快取。
通過上面的具體解釋,現在再來描述上面 Cache-Control
的那段程式碼所表達的意思就好理解多了:
- 本地快取和 CDN 快取均快取 1 小時;
- 不能快取在 CDN,只能快取在本地。並且一旦被快取了,則不能被更新;
- 不能快取。如果一定要快取的話,確保對其進行了二次驗證;
- 本地快取 1 小時,CDN 上快取 2 小時;
- 本地和 CDN 均快取 1 小時。但是如果 CDN 收到請求,則儘管已經快取了 1 小時,還是要檢查源中文件是否已經被改變。