Last-Modified Inspect

キャッシュ関連ヘッダーを横断して判定します。入力はサーバーへ送信しません。再検証やCDN差分の一次切り分けに使えます。

状態

ブラウザ内で処理します。入力はサーバーへ送信しません。まずはここで一次切り分けしてください。

使い方

Last-Modified / If-Modified-Since を貼り付けて「解析」。日時と一致判定を表示します(ヘッダー行/複数行貼り付けOK)。

注意(このツール)

  • 日時はUTC(GMT)として表示します。ブラウザのローカル時刻とは異なる場合があります。

このページについて

何をするツール?

Last-Modified / If-Modified-Since を解析して、日時を読みやすく表示します。両方貼ると一致判定(304の可能性)も表示します。

304が返らない/返りすぎる、キャッシュが効かないといった問題の切り分けに向きます。

Last-Modified の基本

  • Last-Modified は「そのリソースが最後に更新された時刻」です。
  • If-Modified-Since はクライアントが持っている更新時刻を示し、再検証に使われます。
  • サーバーが更新されていないと判断すると 304 を返します。

構文(日時の形式)

HTTP-date は複数形式がありますが、実務では IMF-fixdate がほぼ使われます(例: Sun, 06 Nov 1994 08:49:37 GMT)。

  • Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
  • If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

用語(このページの前提)

  • Revalidation(再検証): キャッシュが有効期限切れ、または no-cache 指定などで「使う前に確認する」動作。
  • Conditional request(条件付きリクエスト): If-Modified-Since や If-None-Match を付けたリクエスト。
  • Fresh / Stale: キャッシュが期限内(fresh)か期限切れ(stale)か。

304(Not Modified)と日時比較

If-Modified-Since の値が Last-Modified 以上であれば、更新なしと判断され 304 が返る可能性があります。

  • 304にならない:Last-Modified が変わっている/付いていない/If-Modified-Since が送られていない
  • 304になりすぎる:Last-Modified が更新されていない/時計ズレ/生成時刻の固定

例(コピペで理解する)

まずはレスポンスヘッダーから Last-Modified を確認し、次にリクエストヘッダーの If-Modified-Since が送られているかを見ます。

  • レスポンス: Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
  • リクエスト: If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT(>= なら 304 になり得る)
  • リクエストが無い: 条件付きリクエストが送られていない → 200 になりやすい

Cache-Control と再検証

Last-Modified は再検証に使われます。Cache-Control の設計次第で再検証が増えたり、そもそも再検証が起きなかったりします。

  • max-age が短い:If-Modified-Since が送られやすい
  • no-cache:毎回再検証(304で本文省略の可能性)
  • immutable:再検証を抑える(ファイル名hashと相性が良い)

304にならない時の典型原因

  • Last-Modified が付いていない(動的レスポンスで省略されがち)
  • If-Modified-Since が送られていない(キャッシュ設計、DevToolsのDisable cache、SWなど)
  • 時計ズレ(サーバー時刻/ビルド時刻/コンテナ時刻)
  • 更新判定が秒未満で起きる(高頻度更新で Last-Modified が追いつかない)

精度の注意(1秒単位)

Last-Modified は秒単位です。高頻度更新やミリ秒精度が必要な場合、ETag 併用や別バージョン管理が必要です。

実装側の注意(生成時刻を入れない)

Last-Modified は「更新された時刻」を表すべきです。毎回の生成時刻(現在時刻)を入れると、条件付きリクエストが成立せず 304 が出なくなります。

  • 静的ファイル: ファイルの mtime を使うのが一般的
  • DB/API: 更新時刻(updated_at)を使う
  • ビルド成果物: ビルド時刻やコミット時刻を使う(ただし全ファイル同時更新扱いになる)

CDN/プロキシ配下の注意

CDNやプロキシは、オリジンの Last-Modified をそのまま返すとは限りません。圧縮や最適化、キャッシュ再構成で変わることがあります。

確認のしかた(curlで再検証する)

実際に Last-Modified を取得し、その値で If-Modified-Since を送ると挙動が確認できます(URLは置き換えてください)。

  • 取得: curl -I https://example.com/asset.js
  • 再検証: curl -I -H \"If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT\" https://example.com/asset.js
  • 比較: ステータス(200/304)と、Last-Modified/Cache-Control を合わせて確認

使いどころ

  • ETagが無い環境での再検証確認
  • 304が返らず毎回200になる
  • キャッシュが効きすぎて更新が反映されない

切り分け手順(おすすめ)

  • Response Headers Parser で Last-Modified / Cache-Control を確認
  • リクエスト側の If-Modified-Since を Request Headers Parser で確認
  • このツールで日時を読みやすくして比較
  • ETag Inspect
  • Cache-Control Inspect
  • Response Headers Parser / Request Headers Parser
  • Vary Inspect

推奨(実務)

  • 更新時刻が確実に変わるように運用(生成時刻ではなく変更時刻)
  • API/HTML は validators(ETag/Last-Modified)を必ず付与
  • Cache-Control と合わせて再検証を成立させる

このツールでできること

  • Last-Modified / If-Modified-Since の日時解析
  • 日時の比較(同じ/新しい/古い)
  • ヘッダー行/複数行貼り付けに対応

注意(運用)

  • キャッシュ挙動はブラウザ/CDN/プロキシの層で変わるため、同一点観測で比較してください。
  • ヘッダー診断だけでは不十分な場合があります。アプリ側の更新戦略とキー設計も確認してください。

参照仕様

  • RFC 9110(HTTP Semantics)
  • RFC 9111(HTTP Caching)
  • MDN: Last-Modified / If-Modified-Since

FAQ

ETag があるなら Last-Modified は不要?

ETagが最優先で使われることが多いですが、Last-Modifiedも補助的に使われる場合があります(クライアントや中間キャッシュの実装次第)。

Last-Modified はどこから決める?

ファイルの更新時刻、DBの更新時刻、ビルド時刻など、リソースの実際の更新を反映できる値を使うのが基本です。

参考リンク

  1. RFC 9110
  2. RFC 9111
  3. MDN: Last-Modified
  4. MDN: If-Modified-Since
  5. MDN: HTTP caching

site_map ルールに基づいて、次に確認すべきページを表示しています。

  1. 304が返らない時の診断手順 — ETag / Last-Modified と If-* の往復を確認して 304 不発を切り分ける
  2. Expires Inspect — Expires / Date を解析して期限挙動を確認
  3. Vary Inspect — Vary を解析してキャッシュ分岐条件を可視化
  4. Age Inspect — Age を解析して共有キャッシュ滞在時間を把握
  5. ETag Inspect — ETag と If-None-Match の整合を解析
  6. Cache Validator Overview — ETag/Last-Modified 系バリデータの関係を整理
  7. ETag Builder — 用途に応じたETag値を生成
  8. If-None-Match Inspect — If-None-Match を解析して再検証条件を確認

キャッシュ検証

ETag/Last-Modified と If-* をつないで再検証フローを判断