Cache-Control ビルダー

Cache-Control ヘッダーを作成、またはディレクティブ・鮮度設定・選択した競合を HTTP リクエストを送信せずに解析します。

ブラウザ内でローカルに実行
このツールの処理はすべてブラウザ内で行われます。VoriTools が入力内容をアップロード・保存したり、外部 API に送信したりすることはありません。
レスポンスポリシーオリジンレスポンスで送信するポリシーを選択します。
Cache-Control 値を解析ディレクティブの値だけ、またはヘッダー行全体を貼り付けてください。

Cache-Control ヘッダーを作成・解析する方法

上のパネルはレスポンスポリシーを組み立てます。可視性を選び、鮮度の期間を秒で入力し、必要なディレクティブにチェックを入れて「ヘッダーを作成」を押します。このページが送信するヘッダーが「レスポンスヘッダー」欄に表示され、その下に3行の概要(ディレクティブ数、レスポンスの鮮度、保存を許可するキャッシュの範囲)と、組み合わせに含まれる競合が並びます。下のパネルは逆方向の作業です。レスポンスや CDN の設定、ログからコピーした値を貼り付けて「ヘッダーを解析」を押すと、同じ概要がそのテキストについて表示されます。どちらもこのブラウザ内で動作し、ページはオフラインでも使えます。

Cache-Control は、キャッシュに「レスポンスをいつまで再利用してよいか」「再利用の前に何を確認すべきか」を伝える HTTP レスポンスフィールドです。max-age と s-maxage はブラウザと共有キャッシュの期間を決め、no-store は保存を禁止し、no-cache は保存を許すものの検証を必須にし、immutable、stale-while-revalidate、stale-if-error がそれを細かく調整します。このツールは RFC 9111 に沿ってヘッダーのテキストを読み、キャッシュがどう解釈するかを示します。URL には一切アクセスしないため、本番のサーバー、CDN、ブラウザキャッシュが実際にどう動くかまでは分かりません。

  1. 「可視性」で対象を選びます。共有キャッシュが保存できるなら public、1人の利用者向けのコピーなら private、フィールドに何も書かないなら「明示的な可視性なし」です。選んだ内容は、表示されているとおりにヘッダーへ書き込まれます。
  2. ブラウザ用に max-age を、CDN やリバースプロキシに独自の期間が必要なら s-maxage を入力します。任意の2つの期間(stale-while-revalidate と stale-if-error)と5つのフラグは、使用したときだけ追加されます。秒数は整数です。3600.9 は切り捨てずに画面が理由を表示するので、3600 のように入力してください。
  3. 「ヘッダーを作成」を押して「レスポンスヘッダー」欄を読みます。送信される形のフィールド行が、フォームが並べた順に表示されます。下の概要はディレクティブ数を数え、鮮度とスコープを示し、見つかった競合(public と private、no-store と鮮度期間、max-age のない immutable、private と s-maxage)をそれぞれ挙げます。
  4. 既にあるヘッダーを確認するには、2つ目のパネルに貼り付けます。ディレクティブの一覧だけでも、Cache-Control 行全体でも構いません。引用符付きの形式も正しく読むため、no-cache="Set-Cookie, Authorization" は1つのディレクティブとして扱われます。未知の名前、重複、引用符で囲まれた delta-seconds、数字以外の値は、黙って通さずに報告します。
  5. 「コピー」はフィールド行をクリップボードへ、「ダウンロード」は cache-control.txt として保存します。「クリア」はフォームを既定値(public と max-age=3600)に戻し、両方のパネルを空にするので、次は同じ状態から始められます。値が読み取れないときは、ステータス行がフィールド名と理由を示し、ヘッダー欄は前回の結果を残さず空になります。

競合、delta-seconds、このツールでは確認できないこと

このツールが報告する競合

public と private は矛盾します。public は共有キャッシュによる保存を許し、private はまさにその共有キャッシュに保存を禁じるため、どちらかを外す必要があります。no-store は最も強いディレクティブで、何も保存できません。同じヘッダーに max-age や s-maxage、古い内容を返す期間があっても意味がなく、概要は適用されない期間を表示する代わりにその点を指摘します。s-maxage を読むのは共有キャッシュだけで、private はそれを排除するため、private と並んだ s-maxage は効果がありません。

immutable は鮮度がある間リソースが変わらないことを約束します(RFC 8246)。max-age も s-maxage もない場合、その約束が及ぶ鮮度の期間が示されていません。must-understand は no-store と一緒に使うもので、そのステータスコードのキャッシュ要件を理解するキャッシュは no-store の部分を無視します(RFC 9111 5.2.2.3)。鮮度期間がない場合も報告します。max-age、s-maxage、no-cache のいずれもないと、キャッシュはヒューリスティック(一般に Last-Modified からの経過時間の10分の1)で判断し、オリジンに問い合わせずに再利用することがあります。

delta-seconds:キャッシュが受け取る数値

max-age、s-maxage、stale-while-revalidate、stale-if-error は delta-seconds を取ります。RFC 9111 では1桁以上の数字と定義され(1.2.2)、0 は有効で「直ちに古い」を意味し、小数点は文法に含まれません。max-age="5" のように引用符で囲んだ値は、送信側がトークン形式を使う必要があるため報告します(5.2.2.1)。2147483647 秒を超える値も指摘します。その数値を表現できないキャッシュは 2147483648 秒(68 年以上、実質いつまでも新鮮)として扱う必要があるためです。

このフィールドのもう一つの引数形式は、no-cache と private の引用符付きフィールド名リストです(例:no-cache="Set-Cookie")。引用符の中のカンマはリストの一部なので、解析器は引用符の外のカンマだけで分割し、その値を1つのディレクティブとして数えます。キャッシュが認識しないディレクティブはそのキャッシュに無視されます(5.2.3)。だからこそ maz-age=60 のような打ち間違いを報告します。レスポンスはそのまま配信され、ルールだけが存在しない状態になるからです。

このツールで分からないこと

このページはリクエストを送信せず、ヘッダーのテキストだけを読みます。CDN、リバースプロキシ、ブラウザがこのフィールドに従うかどうかは、そのシステムの設定とレスポンスのステータスコード次第です。また、ディレクティブが何もないレスポンスでも、ヒューリスティックにキャッシュ可能と判断されれば保存されることがあります。ポリシーは実際のレスポンス(curl -I、CDN が示すキャッシュヘッダー、ブラウザのネットワークパネル)で確認してから信用してください。

このフィールドの隣接項目は対象外です。Expires は期間ではなく絶対日時を示し、Pragma は HTTP/1.0 のリクエストフィールドで RFC 9111 では非推奨です(5.4)。そのため別のフィールド名で始まる行は、Cache-Control と勝手に読み替えず拒否します。そして確認はテキストに対するものなので、きれいに読めるヘッダーでも内容に対して誤っていることがあります。静的アセットへの no-store、毎時変わるページへの1年の max-age は、ヘッダー検査では判断できない設計上の選択です。

最近使ったツール: