こんにちは、 @kz_morita です。
最近, Web配信の技術 - HTTPキャッシュ・リバースプロキシ・CDNを活用する の本を読んでいて,Cache-Control 難しいなと思ったのでメモがてらまとめます.
Web配信の技術 - HTTPキャッシュ・リバースプロキシ・CDNを活用するCache-Control ヘッダー
HTTP でキャッシュに関係する設定を行うヘッダーです.リクエスト時とレスポンス時の両方に指定できるようです.
リクエスト時
Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: no-transform
Cache-Control: only-if-cached
レスポンス時
Cache-Control: must-revalidate
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: no-transform
Cache-Control: public
Cache-Control: private
Cache-Control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-Control: s-maxage=<seconds>
また,対応していないブラウザもありますが,以下の拡張もあります.
Cache-Control: immutable
Cache-Control: stale-while-revalidate=<seconds>
Cache-Control: stale-if-error=<seconds>
- https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Cache-Control
- RFCは HTTP/1.1: キャッシュ処理 (日本語訳) で仕様が策定されています.
キャッシュの種類
キャッシュの性質による種別について書いていきます.
キャッシュには,private
と shared
があります.
private
キャッシュは,クライアント(ブラウザ) にのみキャッシュできるものです.shared
キャッシュは,クライアントの他にネットワーク上の経路でもキャッシュできるものになります.
これは private
キャッシュは,ユーザー単位のキャッシュであるのに対し,複数ユーザー間で共有できるのが shared
キャッシュです.ユーザーの秘匿情報をキャッシュしてしまってセキュリティ事故になってしまったというようなケースは,意図せず shared
キャッシュにしてしまったという原因が考えられます.
以下のように,private を指定すると,shared キャッシュを許可しない設定になります.
Cache-Control: private
キャッシュしない設定
ここでは,キャッシュをしないための設定をまとめます.
MDNによると以下のように,no-store
を設定することが推奨されています.
Cache-Control: no-store
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Cache-Control#preventing_caching
また,冒頭で紹介した書籍には以下のような設定がおすすめされています.
Cache-Control: private, no-store, no-cache, must-revalidate
しかし,MDNでは 悪い例
として以下が紹介されていました.(書籍の記述と近い…)
Cache-Control: private,no-cache,no-store,max-age=0,must-revalidate,pre-check=0,post-check=0
こちらどのような指定が適切かは要検証なのかなと思います.
一応ここに登場した,ディレクティブの説明をします.
Cache-Control: private
先程も軽く触れましたが,shared
キャッシュとして,経路上にキャッシュすることを設定しないディレクティブです.
Cache-Control: no-store
キャッシュを格納しない設定です. private
, shared
両方に適用されます.
Cache-Control: no-cache
オリジンサーバーでの確認なしに,キャッシュを利用しては行けないという指定です.
https://triple-underscore.github.io/RFC7234-ja.html#cache-request-directive.no-cacheCache-Control: must-revalidate
キャッシュの有効期限が切れた際にオリジンサーバーに再検証しに行きますが,その際にオリジンサーバーがダウンなどをした場合に,通常では期限切れのキャッシュでも再利用するという動作をすることがあります.
must-revalidate
を指定すると,必ずオリジンサーバーに問い合わせるようになり,ダウンしたときは 504 Gateway Timeout を返すようになり意図せずキャッシュが使われることを防ぎます.
まとめ
今回は,Cache-Control について簡単にまとめました.結構難しい(キャッシュされるためのフローなど)ですが,あやまると思わぬ事故を招きそうなためもう少し調査などして理解を深めたいと思います.
読んでるけど、いまのところ
— kz_morita 𓆏 (@kz_morita) February 20, 2021
Cache-Control ヘッダ難しすぎるだろっ
という感想 pic.twitter.com/RebCGau8kh