透過 HTTP Cache 讓 CDN 快取特定檔案

這篇來講 HTTP 快取的作法,不論你是要調整檔案快取時間、決定要不要讓 CDN 快取,還是要隨時保持最新的檔案,都可以透過這些 Header 來調整。

透過 HTTP Cache 讓 CDN 快取特定檔案

這篇來講 HTTP 快取的作法,不論你是要調整檔案快取時間、決定要不要讓 CDN 快取,還是要隨時保持最新的檔案,都可以透過這些 Header 來調整。

還記得昨天提到 CloudFlare 的快取機制 中,只會看副檔名而不會去看 MIME Type 嗎?這個意思就是,如果你有一個 API 是 https://example.com/image/3 的話,只要不是 .jpg 結尾,CloudFlare 就不會快取了。但沒關係,我們依然可以透過調整 HTTP Header 來建議 CDN、瀏覽器要不要快取。

這篇中提到的 Header,依然是指 Response Header,一樣可以透過 DevTools 來觀察。

告訴瀏覽器、CDN 要快取多久

首先是透過 cache-control 這個 Header 決定了檔案要快取多久,CDN 能不能快取。通常會使用 max-age 來決定這個快取可以用多久。比方說如果有張圖片的 cache-control: max-age=30 代表這個快取最多用 30 秒,如果使用者在第一次取得這張圖片的 15 秒後又嘗試取得這張圖片,瀏覽器會因為知道這張還沒過期、還能用,所以不跟 Server 拿,直接使用本機的快取(HTTP 200)。

cache_200

Client 經過 CDN 再到遠端 Server 拿,所以對 Client 來說它會存一份快取,CDN 也會存一份快取。如果 Client 快取失效(或是從來沒快取過)了會先跟 CDN 拿,直到 CDN 快取也沒了,才會跟 Server 拿。

如果不想讓 CDN 快取的話,可以加上 private 標籤,例如有張圖片是 cache-control: private, max-age=30 的話,那只有 Client 端會快取圖片,CDN 不會理你,例如在 CloudFlare 上,cf-cache-status 一定是 MISS

過期了還能用嗎?

如果快取已經過期的話,Client 就會嘗試再跟 Server 拿一份。但是並不是每次請求檔案 Server 就會傳一次完整檔案。

例如,Server 可能會在某張圖片加上 Last-modified: 2019-10-06 18:00:00,這樣在就算過期,Client 也會先檢查目前過期的圖片是否仍然新鮮,如果正確的話,Server 就會回傳 HTTP 304 Not Modifed,表示這張快取還可以繼續用。

cache_304

缺點是 Server 如果打開這個檔案再存檔,Last-modified 值可能就會改變,另外一個做法是 Etag 欄位。有點像是去算這個檔案的 hash 值,比對如果 hash 值相同也回傳 HTTP 304 Not Modified,只有 Etag 值不一樣的時候,才會重新從 Server side 拿資料。

結語

這篇大概講了 Server 可以丟什麼 Header 去調整快取機制,並沒有太詳細的介紹這個東西是怎麼處理的;也沒有去提到 Client 端怎麼送 if-modified-since 之類的表頭。這篇先這樣,可以試著在 koa 的 ctx.request.headers 中加入不同的參數去調整快取看看。

本篇文章同步發表在 iT邦幫忙

我們正降低廣告比例以提升閱讀體驗。如果你喜歡這篇文章,不妨按下 Like 按鈕分享到社群,以行動支持我寫更多文章。 當然,你也可以 點此用新臺幣支持我,或 點此透過 BTC、ETH、USDC 等加密貨幣支持我
分享到: