HTTP 304 Not Modified をリクエストごとにシミュレート
ホーム
HTTP 304 Not Modified
HTTP 304 Not Modified:ETag と If-None-Match を解説 | We.Inc
条件付きリクエストをシミュレートします。サーバーの ETag と Last-Modified、ブラウザーの If-None-Match と If-Modified-Since を設定すると、304 か 200 かとその理由が表示されます。
304 Not Modified の応答は、ブラウザーのキャッシュがまだ最新であることを伝え、サーバーは本文の再送を省きます。これは If-None-Match または If-Modified-Since を含む条件付きの GET や HEAD への応答です。304 はエラーではなく良い知らせで、キャッシュしたファイルを使い続けながら帯域を節約できます。
304 の背後にあるバリデーターの組み合わせ
サーバーが送るもの ブラウザーが送り返すもの サーバーが 304 を返す条件
ETag: "v2" If-None-Match: "v2" 列挙されたタグの1つが現在の ETag と一致する(弱い比較)
Last-Modified: <date> If-Modified-Since: <date> その日時以降、リソースが変更されていない
両方 両方 If-None-Match で判定し、If-Modified-Since は無視される
サーバーが現在保持している値とブラウザーが送る値を入力すると、シミュレーターがHTTP仕様の優先順位の規則を適用します。サーバーが返すべきステータスと、どのヘッダーで判定されたかが表示されます。項目を空にすると、そのヘッダーは送られないものとして扱われます。
サーバーが現在そのファイルについて持っている ETag と Last-Modified の値を設定します。 ブラウザーがキャッシュから送る If-None-Match と If-Modified-Since のヘッダーを設定します。 ステータスと理由を読みます。どのヘッダーが評価され、なぜ一致した、またはしなかったのかがわかります。 サーバーの ETag を変えると、デプロイによって次のリクエストが 200 になる様子を確認できます。
304 では、200 なら含まれるはずの Cache-Control、ETag、Vary、Date などのヘッダーを繰り返す必要があります。キャッシュが保存したメタデータを更新できるようにするためです。 app.3f9a1c.js のようなフィンガープリント付きのアセット名と長い max-age を組み合わせれば、再検証そのものが不要になります。ETag による再検証は、HTMLやAPIのレスポンスに使いましょう。 弱い ETag は W/ で始まり、バイト単位の一致ではなく意味的な同一性を約束します。If-None-Match は弱い比較を使うので、弱い ETag でも機能します。 DevTools で転送サイズの小さい 304 の行があれば、ブラウザーの再検証が成功しています。デバッグ中は Network パネルでキャッシュを無効にすると、常に完全な 200 のレスポンスを受け取れます。
よくある質問
304 のレスポンスはエラーですか?
いいえ。キャッシュを使ってよいことを意味する、リダイレクト系のステータスです。ブラウザーはキャッシュからページを表示し、ネットワークを通ったのはヘッダーだけです。
304 のレスポンスに本文を含められますか?
いいえ。仕様では、304 のレスポンスはヘッダー部の終わりで終了し、コンテンツを含められないとされています。
If-None-Match と If-Modified-Since のどちらが優先されますか?
If-None-Match です。リクエストに両方が含まれる場合、エンティティタグに対応したサーバーは If-None-Match を評価し、If-Modified-Since を無視します。タグは、1秒単位の日時では検出できない変更も検出できるためです。
デプロイのたびに 304 ではなく 200 が返るのはなぜですか?
デプロイによってファイルかその ETag が変わったため、ブラウザーが持っているタグが一致しなくなったからです。これは正しい動作です。変更していないファイルまで 304 にならないなら、同じ内容に対してサーバーが異なる ETag を生成していないか確認しましょう。
POST が 304 を返すことはありますか?
ありません。If-None-Match と If-Modified-Since が 304 を生むのは GET と HEAD の場合だけです。他のメソッドでは、条件が満たされないと 412 Precondition Failed になります。
再検証の仕組み
キャッシュしたレスポンスが古くなっても、ブラウザーはそれを捨てません。保存しておいたバリデーター、つまり ETag を If-None-Match として、Last-Modified の日時を If-Modified-Since として送り、手元のコピーがまだ有効かをサーバーに尋ねます。 何も変わっていなければ、サーバーは新しいヘッダーだけで本文のない 304 を返し、ブラウザーは手元のコピーを使い続けます。何かが変わっていれば、サーバーは新しい内容とともに通常の 200 を送ります。
強いタグと弱いタグ
"v2" のような強いタグは、バイトが同一であることを約束します。W/"v2" のような弱いタグは、内容が同等であることだけを約束します。If-None-Match は弱い比較を行うので、W/"v2" と "v2" は一致とみなされますが、If-Match は強い比較を行うので一致しません。
実際の通信内容
初回の訪問:バリデーター付きの 200
サーバーはコンテンツと一緒に ETag と Last-Modified の日時を渡します。
次の訪問:本文なしの 304
ブラウザーは保存したタグを送り返し、ヘッダーだけを受け取ります。
条件付きリクエストに自分で応答する
コンテンツのハッシュを ETag にする Node の http サーバー
本文をハッシュ化して If-None-Match と比較し、一致すれば本文なしで 304 を送ります。
条件付きリクエストのシミュレーター
サーバーが現在保持しているもの
ブラウザーが送るもの
ETag
Last-Modified
If-None-Match
If-Modified-Since
サーバーの応答
If-None-Match に、弱い比較で現在の ETag と一致するタグがあるので、キャッシュは最新です。
If-None-Match が * で、リソースが存在するので、条件は偽になります。
If-None-Match のどのタグも現在の ETag と一致しないので、サーバーは新しい内容を送ります。If-Modified-Since は確認されません。
If-None-Match がなく、Last-Modified が If-Modified-Since より後ではありません。
If-None-Match がなく、Last-Modified が If-Modified-Since より後です。
If-Modified-Since はありますが、2つの日時のどちらかが読み取れないため、このヘッダーは無視されます。
リクエストにバリデーターがないので、通常のリクエストです。
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る