Apache は静的ファイルに対して 304 Not Modified レスポンスを返さない

Apache は静的ファイルに対して 304 Not Modified レスポンスを返さない

私は Apache Web サーバーを実行していて、ファイル システムから大きな静的画像を提供しています。次のように、有効なキャッシュ ヘッダーを返すようにサーバーを構成しました。Header merge Cache-Control "public, max-age=31536000, immutable"

それはすべて良いのですが、ユーザーがブラウザで画像を再読み込みすると、Apache は応答を返しません304 Not Modified

次の curl コマンドを実行しました (機密保持のためホスト名を変更しました)。

curl -o /tmp/image.png -v -u test:example http://blah.example.com/static/images/covers/436g2gu94kxin4x7

以下は curl からのリクエスト ヘッダーです。

GET /static/images/covers/436g2gu94kxin4x7 HTTP/1.1
Host: blah.example.com
Authorization: Basic dGVzdDpleGFtcGxl
User-Agent: curl/7.64.1
Accept: */*
If-Modified-Since: Thu, 30 Apr 2020 02:21:47 GMT

304 応答を期待していましたが、代わりに次の応答が返されました:

HTTP/1.1 200 OK
Date: Fri, 28 Aug 2020 04:59:54 GMT
Server: Apache/2.4.25 (Debian)
Content-Type: image/png
Content-Length: 3115720
Last-Modified: Thu, 30 Apr 2020 02:21:47 GMT
Vary: Accept-Encoding
Cache-Control: public, max-age=31536000, immutable

私は読んだApache キャッシュ ガイド、しかし、そのどれもこの状況には関係ないようです...これはすべて、Apache がオリジン サーバーのリバース プロキシとして機能している場合をサポートするために、メモリ内またはディスク上で Apache 独自のキャッシュを構成することです。

しかし、この場合、ファイルはすでにローカル ディスク上に存在しています。元のサーバーはありません。Apache にファイルの別の「キャッシュされた」コピーを保存させたくはありませんし、その必要もありません。Apache にLast-Modifiedディスク上のファイルの日付が日付と一致していることを知らせて、その場合にIf-Modified-Since返してもらいたいだけです。304 Not Modified

これを設定するにはどうすればよいですか? 条件付き GET を有効にするには、Apache にファイルの独自のキャッシュされたコピーを保存させる必要がありますか? (これは非常に大きなキャッシュになり、おそらくディスクに保存されますが、これはまったくの無駄です。)

答え1

まず、本当にキャッシュされていないのでしょうか?

curl が問題の原因である可能性があります。304 を返すことがわかっている URL であなたのコードを試してみましたが、上記のコードを使用すると常に 200 が返されます。Web ブラウザの開発者ツールを試しましたか? 「キャッシュを無効にする」のチェックが外れている限り、URL を更新して 2 回目の更新で 304 が返されるはずです。

2つ目はApacheのバグである可能性がある

結果に ETag ヘッダーが表示されません。Apache が実際にこれを追加していないと仮定すると、おそらくこれを無視できます。ただし、念のため、Apache 設定にこれを追加してみることをお勧めします。

<IfModule mod_headers.c>
    Header unset ETag
</IfModule>
FileETag None

(必ず でヘッダー モッドを有効にしてくださいa2enmod headers。)

あるいは、Apache バージョン 2.4.42 以降 ( apache2 -v) を使用している場合は、代わりに設定で以下を試すこともできます。

<IfModule mod_deflate.c>
    DeflateAlterETag NoChange
</IfModule>

この問題は、deflate モジュールが ETag の末尾に圧縮メソッドを追加したことが原因でした。これにより、Apache はキャッシュを無視し、常に 200 を返すようになりました。Apache の言葉を借りれば、次のようになります。

...圧縮されたコンテンツに対する条件付きリクエストに対して「HTTP Not Modified」(304)応答が提供されないようにします。

Apache モジュール mod_deflate

そのため、これを無効にすると、一部のキャッシュの問題が解決される可能性があります。

関連情報