iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 21
0

這篇來講 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)。

https://ithelp.ithome.com.tw/upload/images/20191006/20119970D3V8t8PMIw.png

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,表示這張快取還可以繼續用。

https://ithelp.ithome.com.tw/upload/images/20191006/20119970ga7vN4BN7Z.jpg

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

結語

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

本篇文章同步發表在 Noob's Space


上一篇
CloudFlare 快取了什麼?五招設定看這裡
下一篇
Nginx:高效能的 Web 伺服器、反向代理、負載平衡
系列文
前端工程師也該會的後端技倆30

尚未有邦友留言

立即登入留言