メソッドとキャッシュの関係
「このレスポンス、キャッシュされる?」を素早く判断するためのメモです。HTTPの意味を定めるRFC 9110とキャッシュを定めるRFC 9111に沿って、GET/HEAD/POSTの扱いをまとめました。
キャッシュの基本
保存できるかはメソッド・ステータス・ヘッダーで決まります。保存できても、実際に保存するかはブラウザーやCDNの実装・設定次第です。
メソッド別の前提
| メソッド | キャッシュ扱い | ポイント |
|---|---|---|
| GET | 対象 | ステータスや認証、Cache-Controlなどの条件を満たす場合に保存可能。 |
| HEAD | 対象 | GETと同じ扱い。ボディなし。 |
| POST | 原則非対象 | 明示的な鮮度情報と、対象URIと同じ値のContent-Locationが必要。詳細は下記。 |
| PUT/DELETE | 対象外 | これらのメソッドのレスポンスはキャッシュ不可。 |
| PATCH | 条件付きで可能 | RFC 5789では明示的な鮮度情報と対象URIに一致するContent-Locationが必要。後続のGET/HEADだけに再利用できる。 |
主なキャッシュ制御ヘッダー
レスポンスヘッダーがキャッシュの寿命や共有可否を決めます。
ヘッダーまとめ
- Cache-Control: max-age, s-maxage, no-cache, no-store, private, must-revalidate などで寿命と再検証ルールを指定。
- ETag/Last-Modified: 再検証に使うタグや日時。条件付きリクエストとセットで運用。
- Vary: Accept-Languageなど、表現の選択に使ったリクエストヘッダーを指定。アクセス制御やprivateの代わりにはなりません。
- Expires: 鮮度期限を日時で指定。max-ageがあればそちらが優先され、共有キャッシュではs-maxageが優先されます。
POSTレスポンスをキャッシュするとき
仕様上は可能ですが、条件が多いので意図しないキャッシュを避ける設定も重要です。
成立条件
- max-ageやExpiresによる明示的な鮮度情報と、POSTの対象URIと同じ値のContent-Locationが必要です。
- publicだけでは鮮度情報になりません。ステータスやno-storeなど、一般の保存条件も満たす必要があります。
- 保存した応答は後続のGET/HEADに再利用できます。後続のPOSTをキャッシュで処理してはいけません。
- ボディがユーザー固有ならprivateを付けてshared cacheに載らないようにする。
避けたい場合
- Cache-Control: no-store を明示。機密データやトークン発行系では必須。
- Authorization付きの要求への応答は、原則として共有キャッシュで後続の要求に再利用できません。public・s-maxage・must-revalidateには例外を許す意味があります(RFC 9111 §3.5)。個人向け応答へ安易に付けないでください。
再検証と無効化
GET/HEADは条件付きリクエストを活用し、変更時だけ再取得するのが効率的です。
再検証のコツ
- ETagを返し、If-None-Matchで304を返せるようにする。
- 保存させない指定はno-storeです。no-cacheは保存を許し、再利用の前に検証を要求します。max-age=0も保存禁止ではありません。
- ETagの更新やサーバー側のヘッダー変更だけでは、既に新鮮な応答を持つキャッシュへ変更を通知できません。許容できる鮮度期間をあらかじめ設計し、CDNでは必要に応じてパージ機能を利用します。
まとめ
保存の可否と、保存後の再利用条件を分けて考えましょう。更新確認の流れは条件付きリクエストとETag、メソッドの性質はHTTPメソッドの解説を参照してください。
仕様・関連資料
RFC 9110 §9.3.3: POST / RFC 9111: HTTP Caching / RFC 5789 §2: PATCH