Apacheとnginxが提供するすべての404ページにキャッシュなしヘッダーを追加するにはどうすればよいですか?


9

Cloudflareに切り替えた後、最近問題が発生しました。解決策は、基本的にCloudflareが404応答をキャッシュしないようにすることです。

負荷分散されたマルチサーバー設定では、404が時々発生しますが、rsyncによって(lsyncdを介して)すぐに修正されます。Cloudflareの前は、rsyncがその仕事をするので、404edファイルへの再リクエストはすぐに200になります。

ただし、Cloudflareはキャッシュヘッダーに基づいてすべてのデータをキャッシュし、apacheもnginxも404のキャッシュなしヘッダーを送信しないため、Cloudflareは404応答をしばらくキャッシュします。

私はapacheとnginxの両方で404のヘッダーをグローバルに追加するためのソリューションを探していましたが(これはすべてのホストドメインに対して)、これまでのところ空白です。

誰か助けてもらえますか?

ありがとうございました。


同様の質問ですが、Apacheだけです(まだ回答はありません):serverfault.com/questions/331544/…
Artem Russakovskii

これまでのところ、Apacheとnginxの両方で、デフォルトの404ハンドラーによって返されたヘッダーをオーバーライドできないことを確信しています(私に間違いがあることを証明してください!)。私は404ハンドラーをオーバーライドして、そのようなヘッダーをapacheで送信するPHPファイルをポイントすることができましたが、nginxは私の設定でPHPをサポートしていないため、 "expires -1;"を設定します。404の場所では実際には何もしていなかったようですが、nginxでこれを行う方法について私はまだ迷っています。
Artem Russakovskii

回答:


6

error_pageディレクティブを使用して問題を解決し、ヘッダーを追加して場所を個別に処理できませんか?

例えばNginxの場合:

    server {
      ...
      error_page 404 /404.html;
      location = /404.html {
        root   /usr/share/nginx/html;
        add_header Cache-Control "no-cache" always;
      }
    }

1
ここには2つの問題がありますが、それは私が行った方向です。1.私は、デフォルトの404ページを上書きして、すべてのルールを作成する必要がしたくなかったlistenので、location内部にサポートされていませんhttp直接。2.さらに重要なことに、add_headerは20Xおよび30X(nginx.org/en/docs/http/ngx_http_headers_module.html)にのみ適用されるため、スニペットは実際には機能しません。しかし、最近リリースされた1.7.5以降、alwaysすべての応答コードに適用するモディファイアーを追加できるようになったので、幸運です。私はnginxをアップグレードする必要がありましたが、それはお尻の良いキックでした。できます。
Artem Russakovskii

2
回答を更新しました。おそらく、質問を解決するために行ったことを示す回答を追加する必要がありますか?
jimmiw

省略rootしても動作するようです。それが削除された場合、nginxのためにやったこととほぼ同じです。
Artem Russakovskii

Apacheの場合、実際にはカスタムページを使用することを決定したので、ErrorDocument 404 /path/to/my/404.phpにしました。そして、404.php内で<?php // 404ヘッダーをキャッシュしませんでした( "Cache-Control:no-cache、must-revalidate"); // HTTP / 1.1 header( "Expires:Sat、26 Jul 1997 05:00:00 GMT"); //過去の日付?>
Artem Russakovskii

回答を承認しました。誰かが後でより一般的なapacheの回答を提供したい場合、またはperではなくグローバルに機能するnginxの回答を提供したい場合server、彼らは賛成することができます。
Artem Russakovskii

5

あなたもこの方法でそれを行うことができます:

map $status $cache_header {
    default <for_other_codes>;
    404     "no-cache";
}


server {

    [ ... ]

    add_header "Cache-Control" $cache_header always;

}

賢い。他のソリューションを使用するつもりです。既に機能しており、毎回デフォルトのCache-Controlヘッダーを指定する必要がないためです。
Artem Russakovskii

後にセミコロンがありません404 "no-cache"が、stackexchangeの愚かな最小6文字の編集制限により、修正できません。コーディングと構成がすべてのサイトでは、明らかに良い制限ではありません...
nh2

3

Apache 2.4では、次のようなことを試すことができます。

FileETag None
<IfModule mod_headers.c>
    Header always unset ETag "expr=%{REQUEST_STATUS} == 404"
    Header always set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" "expr=%{REQUEST_STATUS} == 404"
    Header always set Pragma "no-cache" "expr=%{REQUEST_STATUS} == 404"
    Header always set Expires "Wed, 11 Jan 1984 05:00:00 GMT" "expr=%{REQUEST_STATUS} == 404"
</IfModule>

これalwaysは次の理由により重要です。

リダイレクトなど、ローカルで生成された非成功(2xx以外)の応答にヘッダーを追加します。この場合、最終応答では、常に対応するテーブルのみが使用されます。

あなたはすべての404を言いましたが、もちろん完全な参照のために、<FilesMatch>それ<LocationMatch>をaでラップするか、スコープを制限することは意味があるかもしれません。

expr条件文の使用はmod_headersドキュメントのバージョン2.2にはないため、これはApache 2.4の新機能だと思います。

curl -I [foo] この構成なしでテスト:

HTTP/1.1 404 Not Found
Date: Thu, 24 May 2018 17:44:29 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Type: text/html; charset=iso-8859-1

curl -I [foo] この構成でテストします。

HTTP/1.1 404 Not Found
Date: Thu, 24 May 2018 17:44:42 GMT
Server: Apache/2.4.18 (Ubuntu)
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Content-Type: text/html; charset=iso-8859-1

出典:

http://httpd.apache.org/docs/current/mod/mod_headers.html


0

問題についての私の5セント-

PHPプロジェクトでは404ページが少ないため、PHPのheader()関数を使用してPHPレベルで実行することにしました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.