HTTP Cache-Control ヘッダー生成ツール|矛盾診断つきディレクティブ組み立て
Cache-Control レスポンスヘッダーを、ラジオボタンとチェックボックスで組み立てるツールです。public / private の可否、max-age・s-maxage・stale-while-revalidate の秒数、must-revalidate や immutable などのフラグを選ぶと、Cache-Control: private, max-age=3600 のような 1 行のヘッダー文字列と、その意味を日本語で説明した文を出力します。さらに「no-store と max-age の同時指定」のような相性の悪い組み合わせを 5 種類のルールで自動診断します。
💡 このツールについて
CDN や Nginx、CloudFront の設定ファイルに Cache-Control を書くとき、ディレクティブの名前は覚えていても「この組み合わせで本当に意図どおり動くのか」が不安になりがちです。とくに no-cache と no-store は名前が似ているのに挙動が真逆で、max-age と一緒に書いたときに何が優先されるかは MDN を毎回開いて確認している人も多いはずです。
このツールは、選んだディレクティブをそのままヘッダー文字列に組み立てるだけでなく、よくある矛盾を指摘します。たとえば no-store を選んだ状態で max-age に値を入れると「no-store が優先され、キャッシュ保存自体が無効」と表示されます。immutable を max-age=0 と組み合わせれば「意味がない」と警告が出ます。設定を本番に反映する前に、組み合わせの妥当性を手元で確認するための下書き用ツールです。
🧐 よくある質問
Q. no-cache と no-store の違いは? no-cache はキャッシュに保存はするものの、使う前に必ずオリジンへ再検証します。no-store はキャッシュへの保存そのものを禁止します。完全に保存させたくない機密データは no-store、最新性を担保しつつ条件付きで再利用したい場合は no-cache を使います。
Q. max-age と s-maxage はどう使い分ける? max-age はブラウザを含むすべてのキャッシュに対する有効期間、s-maxage は CDN やプロキシなどの共有キャッシュ専用の有効期間です。s-maxage を指定すると共有キャッシュ側では max-age より s-maxage が優先されます。
Q. private を選ぶと CDN はどうなる? private は「ブラウザなどの個人キャッシュにのみ保存可」を意味し、CDN・プロキシは保存しません。ユーザーごとに内容が変わるページに使います。共有キャッシュにも保存させたい場合は public を選びます。
Q. 秒数の上限は? max-age・s-maxage・stale-while-revalidate・stale-if-error はいずれも 0〜31536000 秒(1 年)の整数で入力できます。1 年を超える値を入れても 31536000 に丸められます。
Q. immutable は何のため? immutable は「有効期間内はファイルが変わらない」とブラウザに伝えるディレクティブで、リロード時の条件付きリクエストを省けます。ハッシュ付きファイル名の静的アセットなど、内容が変わらない URL に対して max-age を長めに設定して使います。
📚 Cache-Control 豆知識
Cache-Control ヘッダーは HTTP/1.1 で導入され、現在は RFC 9111(HTTP Caching)で仕様が整理されています。それ以前の HTTP/1.0 では Expires ヘッダーで絶対時刻を指定していましたが、サーバーとクライアントの時計のずれに弱いという欠点がありました。max-age による相対秒数の指定は、この時計ずれ問題を回避するために導入された経緯があります。
国内の Web 開発では、画像や JS・CSS などの静的アセットに長い max-age と immutable を付け、HTML には no-cache を付けるという二段構えがよく採られます。ファイル名にビルドハッシュを埋め込み、内容が変われば URL ごと変わる仕組みと組み合わせることで、キャッシュ更新の取りこぼしを防ぎながら配信を高速化できます。