這陣子因為工作的關係跟 Cache 有了接觸的機會,從系統底層一直到網路的傳輸多少都有些涉略,也因此想將這陣子所學做些整理。 首先本文想先介紹 HTTP 的 Cache 機制,其主要目的,簡單講就是減少 Client 端 (主要為 Browser)與 Server 端之間的資料傳輸的次數和資料量。

下面就來針對 HTTP 1.0/1.1 的 Cache 機制作個就介紹。

HTTP 1.0

在 HTTP 1.0 時就有提供 ExpiresPragmaLast-ModifiedIf-Modified-Since 這幾個 Header 來達成 Cache 的效果。

Expires

用來定義 Cache 資料的過期時間 t,以此來告訴 Browser 資料在 t 時間後才需要更新資料。

img_expires

如上圖,Server 告訴 Client 這個 Response 在 Thu, 09 Aug 2018 00:00:00 GMT 後才過期。而 Client 在這個時間到之前就不會再發出 Request 跟 Server 要資料。

Expires 有一缺點,其是回傳特定的時間點 t ,若 Client 有調整過系統時間或是因不同時區造成其時間為 t’t < t’,則 Expires 就會失去Cache 的效果,同樣發出 Request 來拿資料 (如下圖)。

img_expire_issue

Pragma : no-cache

用來讓 Client 告訴 Proxy 是否使用 Cache。

img_pragma 若有 no-cache ,則 Proxy 會再向來源 Server 發送 Request 取得資料; 若無 no-cache ,則直接由 Proxy 回覆 Cached 的資料

Last-Modified / If-Modified-Since

顧名思義,Server 在 Response 回傳特定的時間點在 Last-Modified ,而後續 Client 就將這個時間放在 If-Modified-Since 來告訴 Server,Client 的 Cache 是哪個時間點的資料,來判斷是否要回傳新的資料和時間。

last-if


HTTP 1.1

在 HTTP 1.1 針對 Cache 增加了像是 Cache-Control, ETag…等,來完整 Cache 機制

ETag / If-None-Match

ETag 通常會是一段 Server 產生的 hash 字串,例如:UOqMY6DFJ/mlGYgYDOfJGg== ,而這字串就是給 Client 後續驗證資料是否有更動的依據,就像是透過 MD5 驗證檔案有沒有被更改。

If-None-Match 則是 Client 收到 Server 的 ETag hash 字串之後,在 Request 用這個 Header 並夾帶 hash 字串,讓 Server 驗證請求的資料是否有變動。

  • 若沒變動,則回傳 304 Not Modified 告知 Client,並且可在 Response 中再夾帶 cache-control: Max-Age 讓 Client 重新計算資料的 Timeout 時間。

304

  • 若有變動,則回傳 200 OK 和新的資料,並在 Response 中夾帶新的 ETag 和 cache-control: Max-Age。

200


Reference