Last-modifiedがIf-modified-sinceと一致するのに、Apacheが200 OKを送信するのはなぜですか?


10

私は私のキャッシング戦略に関して基本的な振る舞いをしようとしています:ファイルはキャッシュされ、毎回サーバーで再検証されるべきです。それで、Apacheに304を送り返してもらいたいのです。

ブラウザの更新ごとに発生するダイアログは次のとおりです。

Status Code:200 OK

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie: ...
Host:...
If-Modified-Since:Tue, 14 Oct 2014 15:10:37 GMT
If-None-Match:"1461-505636af08fcd-gzip"
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

Response Headers

Accept-Ranges:bytes
Cache-Control:No-cache
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:1412
Content-Type:text/html
Date:Tue, 14 Oct 2014 16:58:05 GMT
ETag:"1461-505636af08fcd-gzip"
Keep-Alive:timeout=5, max=99
Last-Modified:Tue, 14 Oct 2014 15:10:37 GMT
Server:Apache/2.4.6 (Ubuntu)
Vary:Accept-Encoding

(これはChrome devtoolsからのもので、Disable cacheはオフになっています)

応答にCache-Control:No-cacheヘッダーが含まれていること、およびIf-modified-sinceヘッダーがLast-modifiedと一致していることがわかります。ETagも一致します。

その場合、Apacheは304を送信すべきではありませんか?

編集

ApacheでETagを無効にする

 Header  unset ETag

キャッシュ動作をより予測可能にします...


私が思うにCache-Control:max-age=0、あなたが見るので、キャッシュを無効にCache-Control:No-cache応答を。
ThoriumBR 2014年

私は、apache構成でCache-Control:No-cacheを明示的に設定しました。これは、w3.org/Protocols/rfc2616/rfc2616 - sec14.html#sec14.9.1から、リクエストごとに再検証が発生することを理解しているためです。再検証はファイルの再送信を意味しますか?私は場合は、修正-以来、それは200か304かどうかを決定するために使用すべきであると言うでしょう
、ZR Z

回答:


8

これは古いバグのようで、なぜHeader unset ETag違いが生じるのかを説明しています。

Apache 2.4.0+は自動的に(ヘッダーに表示されるように)圧縮メソッド名をETagに追加し、304応答を防止します。

mod_deflateをサポートの最新バージョンDeflateAlterETagこの動作を制御するために使用することができます。

DeflateAlterETag NoChange

3
これは正しいですが、Apache 2.4にはそのオプションが含まれていません。Apache2.5のみです。ただし、個人的には、Apacheがファイルの内容ではなく最終変更日を基準にしているため、ETagはそれほど有用ではありません。そのため、ETagをオフにすると、最終変更日に基づくIf-Modified-Sinceヘッダーにフォールバックします。ApacheのETagを変更して、サイズ、最終変更、および/またはiノードに基づくようにすることができます-サイズと最終変更がデフォルトです-ただし、ファイルの内容のチェックサムに基づいてETagを計算するオプションが追加されるまで、その限定使用の私見。だから私はそれらをオフにします。
Barry Pollard

1
@BazzaDPそれは理にかなっています。2.5にもそれを行うDeflateAlterETag Removeオプションがあります
Mathias R. Jessen

0

これは少し奇妙なものとしてリクエストで目立ちます:

Cache-Control:max-age=0

しかし、おそらくもっと重要なのは、返されるコンテンツがhtmlであることに気づきました。動的に生成されていますか?Apacheは304応答を送信できますが、静的コンテンツを提供しているのでない限り、その呼び出しを行うのはApacheの仕事ではなく、アプリケーションロジックに依存します。たとえば、ほとんどのphpアプリケーションでは、そのようなものに対するサポートが制限されています。

キャッシュアプ​​リは変更時間やetagなどをチェックできるため、フロントエンドキャッシュが役立つ場合がありますが、これは、アプリケーションとリクエストヘッダーの両方がキャッシュに対応している場合に限られます。たとえば、アプリケーションはコンテンツがキャッシュ可能であることを示すために適切なヘッダーを設定する必要があり、リクエストのCache-controlヘッダーのようなものはキャッシュを無効にします。ヘッダーはキャッシュフレンドリではありません。


要求されたファイルは静的なhtmlファイルであり、Apacheは修正時刻を正しく取得します。(最終更新:2014年10月14日火曜日15:10:37 GMT)。max-age = 0ヘッダーは、URLを入力してEnterキーを押したときにChromeから送信されるリクエストに含まれています。以前の回答のためにありますか?
zrz 2014年

ChromeがリクエストにCache-Control:max-age = 0を自動的に追加することを読みました(Chromeを初めてロードするときを除き、URLを入力してEnterキーを押します)。しかし、それは他のサーバーには影響しないようです(CDNはリクエストにmax-age = 0を指定しても304を送信します)。
zrz 2014年

@zrz:中間キャッシングの制限はデバッグ時に非常に役立ちますが、それ以外の場合はパフォーマンスに悪影響を及ぼします。Chromeで何を読んでいるかを確認します。apacheが何をするかという点では、かなり設定可能です。キャッシュ制御は、元のサーバー用ではなく、中間キャッシュ用の命令です。ただし、Apacheは中間キャッシュとして機能し、あらゆる種類の処理を実行するように構成できます。アンチキャッシングの指示を外すと、オリジンサーバーに期待するような動作が得られると思います。
mc0e 2014年

0

でApacheを構成している場合Cache-Control:No-cache、ApacheはをHTTP 304 Not modifiedクライアントに送信しません。

一部のリクエストを再検証する場合はCache-Control:No-cache、それを必要とするページにのみを配置します。すべてのリソースを再検証する必要はなく、そうすることで帯域幅を浪費しています。


「再検証」という言葉に戸惑っています。私にとっては、それが304かどうかを確認することを意味します。
zrz 2014年

あなたは間違っている。再検証は、データをもう一度クライアントに送信し、すでに同じ情報が含まれている場合でも、すべてをもう一度読み取らせることです。基本的に、すべてのクライアントのキャッシュを無効にします。
ThoriumBR 2014年

それは多くのことを説明しています。最後に、Apacheは一部のリソース(pngなど)に対して304を送信することを念頭に置いて説明する必要がありますが、Cache-Controlは応答でNo-cacheを設定せず、要求でmax-age = 0に設定します。どんな手掛かり ?
zrz 2014年

@ThoriumBR私があなたを正しく解釈したなら、あなたの答えはどちらもここでは正しくありません。no-cache(no-storeではなく)は、「キャッシュしない」という意味ではなく、コンテンツが変更されていない場合は304になる可能性があります。実際、OPはこれを期待していましたが、etagの問題が原因で取得できませんでした。must-revalidateは、古いコンテンツの処理方法に関連し、常に「データをもう一度」送信するわけではありません。
ニック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.