Apacheから強制的にキャッシュを使わせないようにする方法 | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

動的なプログラムでコンテンツを管理している場合、HTTPヘッダを制御できるのでキャッシュコントロールがしやすいですが、静的なHTMLだけの場合はキャッシュの制御がかなり難しい状況になります。

HTMLの場合、METAタグにcache-controlやExpiresを入れるやり方が一般的ですが、この方法はブラウザによって動作にばらつきが出たりそもそも動作が安定しなかったり、プロキシなどを介するN/W上ではMETAタグは無視されるのでうまくキャッシュを制御することができません。


今回の内容は、コンテンツをキャッシュさせるというやり方ではなく、静的なコンテンツしか動いていないWebサーバーという状況下で、コンテンツをキャッシュさせたくない場合の対応方法を書いていきます。



Apacheからキャッシュを使わないことを強制する


先ほども書いたように動的なプログラムを扱っている場合はHTTPヘッダを制御できますが、静的なHTMLだけではHTTPヘッダを制御することができません。

この場合、例えばWebサーバー上のページを更新した場合とかにキャッシュが使われているクライアントとそうではないクライアントが出てきたり、一部のコンテンツだけキャッシュが聞いてしまってレイアウトが崩れてしまったりという現象を引き起こしてしまいます。


こういうときに、Apache側からHTTPヘッダを制御して強制的にキャッシュを使わないようにコントロールすることができたりします。

この設定は、Apacheのモジュールであるmod_headers を利用します。

まず、Apacheの設定ファイル(httpd.conf)に、下記のようにモジュールがロードされているかを確認します。


LoadModule headers_module modules/mod_headers.so

キャッシュをさせない設定方法は、httpd.conf(または、.htaccessを配置)に下記のように記載します。


FileEtag None
RequestHeader unset If-Modified-Since
Header set Cache-Control no-store


設定内容は上から、Etagをつけないようにし、リクエストヘッダに含まれるIf-Modified-Sinceの値をクリアし、レスポンスヘッダにCache-Controlに「no-store」をつけて送信するというものです。


Cache-Controlにno-chacheを指定した場合は、キャッシュされる可能性があるので注意。

結構、no-chacheという記述をキャッシュさせないようにするという風に解説している記事がありますが、正確にはno-chacheでもキャッシュが有効かどうかはWebサーバー側に問い合わせられ、EtagやIf-Modified-Sinceなどによりキャッシュが有効と判断されてしまう場合があります。


参考: プロキシキャッシュ対策 @ IPA ISEC セキュア・プログラミング講座


なので、Cache-Controlにno-storeを指定してキャッシュするなということをレスポンスヘッダに加えています。

逆に、キャッシュの判断基準を潰すという意味では、EtagとかIf-Modified-Sinceだけを指定していてもキャッシュが効かなくなるような気はしますが、優先順位がブラウザによって異なってきたりするみたいなので念のために全て指定しておいたほうが安全かもしれません。


今回の設定内容では、全コンテンツに対して適用されてしまうので、個別にJavaScriptファイルやCSSファイルなど対象を決めて設定したい場合は下記のようにしておきます。


<Files ~ "\.(css|js)$">
    FileEtag None
    RequestHeader unset If-Modified-Since
    Header set Cache-Control no-store
</Files>


あとは、HTTP通信の状況を確認できる状況から実際にキャッシュがされていないか(HTTPステータスコードが304ではなく200になっているか)を確認してみましょう。


A Day In The Boy&#39;s Life-HTTP通信でキャッシュが使われていないか確認


今回の内容は、静的コンテンツしか扱えない状況という前提ですので、動的なプログラムを使っている場合は、そこから出力されるHTTPヘッダの状況もみて変更した方がよいでしょう。


それと、この設定によりキャッシュが使われなくなるということはサーバー側の負荷やクライアント側の動作にも多少なりとも影響が出ることにはなるので、コンテンツを更新する前後など期間を決めて運用するという方がよいかもしれません。