Cache-Control header 淺談

Cache-Control 是一個 HTTP header 。剛好他可以放在 request 與 response 裡面。但裡面的 directive 五花八門,令人難以理解。本篇介紹這些我所知道的 directives ,希望能給個易懂的解釋。

Request headers

作為一個 request header ,他通常沒什麼用。最大的功用可能是讓瀏覽器知道他不要使用 cache 來回覆你。我在 chrome developer tools 裡面打勾 Disable cache 之後, no-cache 就被自動加到 request header 裡面了。

或者有寫 CDN 可能會有特定的暗號,一旦接收到此 header ,該 CDN 就不會返回 cache 的結果。但我們通常不知道這個暗號,所以沒啥實際作用。

Response headers

Cache-Control 同時也可以作為 response header ,並且比起 request header 實用的多。他可以告訴瀏覽器,或是中間的 CDN 節點,到底 cache TTL 設定成多久才算合適。有些東西很適合設定很長的 cache TTL ,例如圖片。而且圖片通常不會更新,要更新的話,通常也會連路徑與圖片名稱一起換掉。對於圖片我們通常設定超長的 TTL 。

但有些 API 就沒辦法了,例如報時的 API 就完全沒有 cache 的必要。

但有些就比較模糊了。例如取得目前排行榜的 API 。感覺上對於時效性 (freshness) 有一定的需求,但又不是真的那麼需要最新的資訊。這時候通常就會評估適當的 cache TTL 。

max-age

我們可以設定 response header cache-control 來指導 CDN 或是瀏覽器該如何判斷 cache 過期時間。舉例來說,裡面可以設定 max-age=600 表示這個資源可以 cache 十分鐘。通常瀏覽器與 CDN 會遵照此值進行 cache 的儲存與過期的判斷。

s-maxage

如果想要瀏覽器 (client side) 與 CDN (server side) 有不同的緩存時間,可以考慮使用 s-maxage 。這個欄位指的是給 shared cache 的指導原則,因此只會對 CDN 起作用,瀏覽器則不會理他。

stale-while-revalidate

我們把存活時間超過 max-age/s-maxage 的資源,稱為 stale 資源。

正常情況下,這些資源超過了 TTL ,因此無法直接回應給用戶端。我們需要回源進行一次確認,並更新 TTL 。通常這個回源確認是需要一點時間的,如果 CDN 節點跟背後的源站距離較遠,這個延遲會很明顯,因為這整個過程需要等待源站回應,算是一種 synchronous 操作所產生的等待。

於是現在就有了這個規格,在這段 stale 的時間內,可以先回應客戶端 stale 資源,然後以 asynchronous 的方式回源確認。

舉例來說,stale-while-revalidate=86400 表示 cache 過期一天內,仍然可以回應給客戶,但必須同時做 asynchronous 的回源,確保下一個用戶可以取得新版資源。

stale-if-error

除非不得已,我們不太希望 5xx 錯誤的內容直接讓用戶端看到。可以設定 stale-if-error 來告訴瀏覽器或 CDN ,在變成 stale 之後的多久內,如果源站回應錯誤,仍然回應之前的 stale 內容給用戶端。相當於某種程度上掩飾的源站出錯。可能會對用戶端比較友善,但可能也因此把出錯藏起來了,導致真的要調查問題時比較難以重現。

值得注意的是,相較於 stale-while-revalidate ,這個 header 並沒有 asynchrnous 回源的現象。


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *