20

次の状況で HTTP キャッシュ ヘッダーを作成するのに問題があります。

私たちのサーバーには、おそらく週に数回変更される大規模なデータがあります。ブラウザがこのデータをキャッシュするようにします。さらに、ネットワークの信頼性が低いため、条件付き get からの待機時間を最小限に抑えたいと考えています。

私が求めている最終的な動作は次のとおりです。

  1. クライアントは、以前に見たことのないリソースを要求します。
  2. max-ageサーバーは、ETag および(24 時間)と共にリソースで応答します。
  3. 24 時間が経過するまで、クライアントはキャッシュされたリソースを使用します。
  4. 有効期限後、クライアントは検証リクエストを実行します ( If-None-Match: [etag])
  5. リソースが変更されていない場合:
    • サーバーは次のように応答します304 Not Modified
    • クライアントは、既存のリソースが今から 24 時間後に新しい有効期限を持つことを何らかの方法で通知されます
    • ステップ3に戻る

要するに、304 応答に新しいmax-age? それとも、オリジナルmax-ageはその後のリクエストに対して尊重されますか?

4

1 に答える 1

29

はい、304 応答には、新しいmax-age(または ETag やその他の応答ヘッダー) を含めることができます。

オリジナルの max-age と新しい max-age のどちらが優先されるかを Firefox 4 で実験したところ、新しいのmax-ageが優先されるので、やりたいことを実装できるはずです。

はではなく、応答ヘッダーにmax-age関連していることを覚えておくことが重要です。そのため、サーバーが 24 時間のディレクティブを設定すると、「今から 24 時間後」と表示されます。したがって、それがあなたが望むものであると仮定すると、まったく変更する必要はなく、常に 86400 を返すだけです。DateLast-Modifiedmax-agemax-age

とにかく、ここに私の実験の概要とダンプがあります。基本的に、ETag を設定max-ageして 120 秒に設定したテスト URL にアクセスしました。したがって、サーバーは次の応答ヘッダーを含むページを返しました。

HTTP/1.1 200 OK
Date: Tue, 14 Jun 2011 23:48:51 GMT
Cache-Control: max-age=120
Etag: "901ea3d0ac9303ae4855a09676f96701"
Last-Modified: Mon, 13 Jun 2011 22:20:03 GMT

次に、アドレスバーで「Enter」を押してページをロードします(ただし、ハードリロードは強制しません)。Firefox がキャッシュからページを繰り返しリロードしたため、ネットワーク トラフィックはありませんでした。その後、120 秒が経過した後、次に Enter キーを押したときに、予想どおり、Firefox は代わりに条件付き GET をサーバーに送信しました。サーバーからの要求と応答は次のとおりです。

GET /example HTTP/1.1
If-Modified-Since: Mon, 13 Jun 2011 22:20:03 GMT
If-None-Match: "901ea3d0ac9303ae4855a09676f96701"

HTTP/1.1 304 Not Modified
Date: Tue, 14 Jun 2011 23:50:54 GMT
Etag: "901ea3d0ac9303ae4855a09676f96701"
Cache-Control: max-age=240

304 応答で、サーバーがmax-age120 秒から 240 秒に変更されたことに注意してください。

では、大きな問題は、120 秒後に何が起こるかということです。Firefox は新しいものを尊重し、max-ageキャッシュからページをロードし続けますか、それともサーバーにヒットしますか? 答えは、キャッシュからページをロードし続け、240 秒に達するまで再要求しなかったことです。

GET /example HTTP/1.1
If-Modified-Since: Mon, 13 Jun 2011 22:20:03 GMT
If-None-Match: "901ea3d0ac9303ae4855a09676f96701"

HTTP/1.1 304 Not Modified
Date: Tue, 14 Jun 2011 23:54:56 GMT
Etag: "901ea3d0ac9303ae4855a09676f96701"
Cache-Control: max-age=240

別の 240 秒のサイクルを繰り返したところ、期待どおりに機能しました。それで、うまくいけば、それはあなたの質問に答えます.

RFCは、年齢の計算がどのように実装されることになっているのか、および他の Cache-Control パラメータがどのように機能するのかを説明しています。すべてのブラウザとプロキシがルールに従うという保証はありませんが、現時点では HTTP 1.1 はかなり古いものであり、ほとんどのブラウザとプロキシは Firefox と同じように動作すると予想できます。

(注:これらのサンプル ダンプを簡潔にするために、ホスト、接続/キープアライブ、コンテンツ エンコーディング/長さ/タイプ、ユーザー エージェントなどの無関係なヘッダーを削除しました。)

于 2011-06-15T00:31:54.737 に答える