メニューを開く

2019/11/24

Apache ~ .htaccess設定方法と使い方 キャッシュ制御~

.htaccessファイルは、分散設定ファイルとも呼ばれ、Webサーバーの挙動を設定することができるファイルのひとつで、WebサーバーとしてApacheが使用されていて、管理者が.htaccessファイルの設置を許可していれば使用することができます。

設定方法


Apacheは、http.confにディレクティブという命令を記述することで設定しますが、http.confは管理者にしか編集できなくなっています。それに対して、.htaccessファイルは各ユーザーがディレクトリ単位に設定することができます。ファイルの構文は、主設定ファイルのhttp.confファイルと同じです。
注意事項
  • 基本的に、http.confファイルにアクセスできない場合以外は極力使用しない
  • FTPで転送する場合、ASCIIモードまたは、テキストモードを使用する
  • Windowsで編集する場合、一旦htaccess.txtなどに置き換え、サーバーに配置後にリネームする
  • 設置されたディレクトリと配下ディレクトリ全てに影響する
  • 構文誤りや管理者が許可していないディレクティブを使用した場合、該当ディレクトリ配下のファイルアクセスが、500 Internal Server Errorになる
  • 最終行には、改行を入れる

使い方

いろんな使い方ができるみたいですが。ざっくりとですが、こんなことができるみたいです。勉強しながら少しずつ記事にしていきたいと思っています。

使い方概要
  • セキュリティ関連
  • エラーページ制御
  • キャッシュ制御
  • ページ表示の高速化
  • 多言語対応
今回は、キャッシュ制御について記事を書きます。
キャッシュ制御
  • mod_expiresモジュール
  • FileETagディレクティブ

Webページの表示速度を向上させる方法のひとつとして、ブラウザのキャッシュ制御があります。キャッシュを制御することで、応答時間の短縮やサーバーリソースが節約出来たりします。PageSpeed Insightsブラウザのキャッシュを活用する方法が記載されていますので参考にして下さい。

mod_expiresモジュール
このモジュールで、サーバーの応答のExpiresヘッダとCache-Controlヘッダのmax-ageディレクティブの設定を制御することができます。元のファイルが作成された時刻もしくは、クライアントのアクセス時刻のどちらかに基づいて有効期限を設定することができます。

Expiresヘッダの設定
記述例
<ifModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access time plus 10 minutes"
  ExpiresByType text/html "access time plus 10 seconds"
  ExpiresByType image/jpg "access time plus 7 days"
                        ...
  ExpiresByType text/css "access time plus 1 month"
                        ...
</ifModule>
ExpiresActiveディレクティブ
ExpiresとCache-Controlヘッダを有効にするか無効にするかを決めます。Offに設定された場合には、ヘッダは生成されません。Onに設定された場合には、ヘッダはExpiresByTypeディレクティブとExpiresDefaultディレクティブの基準に従い文書にヘッダを追加します。ExpiresとCache-Controlヘッダの存在を保証する訳でなく、基準が満たされない場合にはヘッダは追加されません。

ExpiresDefaultディレクティブ
全てのドキュメントに対して、デフォルトの有効期限を設定できます。また、ExpiresByTypeディレクティブを使うことでタイプ毎に上書きすることができます。
構文
ExpiresDefault <code>seconds
<code> :基準時刻をファイルの最終修正時刻(M)にするか、クライアントのアクセス時間(A)にするかを指定
second  :有効期限の日時を設定するための基準時刻に追加する秒数を設定
             ExpiresActive On
             ExpiresDefault A2592000
FilesMatchディレクティブを使用することで拡張子を指定することができます。
<FilesMatch "\.(jpg|png|js|css|)(\.gz)?$">
  ExpiresDefault A2592000
</FilesMatch>

ExpiresByTypeディレクティブ
指定したタイプのドキュメントに対して生成されるExpiresヘッダとCache-Controlヘッダのmax-ageディレクティブの値を定義できます。
構文
ExpiresByType MIME-type <code>seconds
MIME-type:キャッシュしたいファイルの種類を指定
<code> :基準時刻をファイルの最終修正時刻(M)にするか、クライアントのアクセス時間(A)にするかを指定
second:有効期限の日時を設定するための基準時刻に追加する秒数を設定
Cache-Control:max-ageは期限切れの時刻からリクエスト時刻を引いた秒数で設定する。
ExpiresActive On
#pngファイルはアクセス日時から1ヶ月間有効
ExpiresByType image/gif A2592000
#HTMLファイルは最終更新日時から1週間有効
ExpiresByType text/html M604600

代替期間指定構文
ExpiresDefaultディレクティブとExpiresByTypeディレクティブは、下記の構文で定義できます。
構文
ExpiresDefault "<base> [plus] {<num> <type>}*"
ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"
base
 access:基準時刻をクライアントのドキュメントへのアクセス時刻にする
 now:'access’と同じ
 modification:基準時刻をファイルの最終更新時刻にする
plus
 plusキーワードは省略可能
num
 整数値
Type
 years
 months
 weeks
 days
 hours
 minutes
 seconds

Cache-Controlヘッダ 
Cache-Controlヘッダのmax-ageディレクティブを使いリソースの有効期限を設定することもできます。Headerディレクティブの引数にsetを指定することで応答ヘッダを設定します。Apacheモジュールmod_headers参照。
引数に空白文字が含まれている場合には、引数をダブルクォーテーションで囲む必要があります。
Header set header [value]
Cache-Controlヘッダは、HTTP/1.1仕様の1部として定義され、レスポンス、キャッシュ、ポリシーの設定に使用されていたヘッダーよりも優先されます。古いブラウザの中には対応しないものも存在します。
Cache-ControlとExpiresの両方を記述した場合には、Cache-Controlの設定が優先されます。
ExpiresActive On
Header set Connection keep-alive
<FilesMatch "\.(jpg|jpeg|png)$">
  Header set Cache-Control "max-age=2592000,public"
</FilesMatch>
<FilesMatch "\.(js|css)$">
  Header set Cache-Control "max-age=1209600,private"
</FilesMatch>
<FilesMatch "\.(html)$">
  Header set Cache-Control "max-age=600,must-revalidate"
</FilesMatch> 
public:どのキャッシュでもレスポンスを保存することを示す
private:レスポンスが1人のユーザーのものであり、キャッシュを共有保存しないことを示し、ブラウザのプライベートキャッシュはレスポンスを保存できます
must-revalidate:キャッシュに記録されているコンテンツが有効か否かをWebサーバーに必ず問い合わせます
no-cache:キャッシュしたものが有効か否かサーバーでの確認なしにキャッシュを利用しない
no-store:キャッシュしない

キャッシュを解除する方法
キャッシュの設定を行うと、有効期間内はブラウザのキャッシュを読み込むようになり、JavaScriptやCSSファイルを更新しても反映されないということが起こります。

クエリ文字列を付加する
キャッシュを有効にしながら、新しいファイルを強制的に読み込ませる方法の1つは、?で始まる適当なクエリ文字列をファイル名の末尾に加えます。こうすることで、ブラウザはそのクエリ付きのURLをまだ取得出来ていないファイルと認識して、キャッシュを読み込まずにサーバーからファイルを取得します。
<link rel="stylesheet" href="../css/style.css?20191124" type="text/css">
<script type="text/javascript" src="../js/base.js?date=20191124"></script>
<img src="image/gazou.jpg?20191124" alt="">
通常クエリ文字列を加える場合は、“?”の後に“name=value”の形式で付与しますが、キャッシュを解除する場合には、“name=value”の形式にする必要はありません。
PHPの場合には、filemtime()(../php/php_basic_04.php#filemtime)を使用すると便利です。
<?php
echo '<link rel="stylesheet" href="../css/style.css?' . filemtime('../css/style.css') . '">';
?>

URLを変更する
URLを変更するとブラウザはキャッシュは読み込まずにリソースを強制的に再取得します。実際のURLを変更するのではなく、HTMLの読み込み側のURLを変更します。例えば、style.cssをstyle.3210.cssに変更します。
<link rel="stylesheet" href="css/style.3210.css">
あわせて、.htaccessに下記のように“ファイル名.数値.拡張子”を“ファイル名.拡張子”にする修正を加えることで正しいcssファイルを読み込むようにする必要があります。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L] 

キャッシュさせない
Apacheからブラウザに強制的にキャッシュさせないようにするには、How To Prevent HTTP File Caching With .htaccessを参考に.htaccessを修正します。

FileETagディレクティブ
ETagは、サーバー上に存在するファイルとブラウザのキャッシュ内のファイルが一致するを判断するためのタグのことで、ブラウザからIf-None-Matchタグにこの値が付けられ、サーバー側でこの値とETagの値が異なればレスポンスコード200(OK)でコンテンツが送信され、同一なら304(変更なし)として処理されキャッシュを使用することでキャッシュの効率化、回線の帯域の節約ができます。

FileETagディレクティブは、ETag応答ヘッダフィールドを作成する時に使用するファイルの属性を設定します。詳細は、Apache コア機能 FileETag ディレクティブを参照して下さい。

負荷分散のためにWebサーバーが複数台ある場合には、ファイルが同一でもinodeがサーバー毎に異なるため200を返す可能性があり、inodeを使わないようにしたり、検証をしないように設定したほうが良いこともあるそうです。詳しくは、ブラウザキャッシュでパフォーマンス向上―負荷分散装置の落とし穴に注意-を参照して下さい。

Headerディレクティブを使用して、ETag応答ヘッダを削除する方法は、Apache モジュール mod_headers Header ディレクティブを参考に下記のように記述します。
Header unset ETag
FileETag None

Apache1.3.23以降では、サーバー側でETagをつけないことでETag比較を行わなく出来るそうです。
 FileETag None 


EmoticonEmoticon