htaccessのリダイレクトですが、理解していますか?
なんとなーく、理解しているけど、細かい事はわからない。
そうゆう方多いと思います。
ダメ!!!
それじゃあダメ。
ちゃんと理解しないと、ある日リダイレクトの永久ループにはまる事になります。。。
●そもそもhtaccessとは何か?
htaccessとは、Webサーバーで使用される設定ファイルの一つです。
本来はサーバー内で設定するものですが、htaccessを使うことで、ディレクトリ単位で設定を変更することができます。
サーバー内で設定するのが正しいのですが、サーバー内で設定した場合のやっかいなのが、設定を変更した際にサーバー再起動が必要になります。
これがめんどい。
この設定を、htaccessで行うことで、サーバー再起動なしで設定を変更できるようになります。
すごく簡単!!
htaccessで出来る事は色々ありますが、よく使うのは以下の5つ
・リダイレクト設定
・アクセス制限
・エラーページ設定
・BASIC認証
・キャッシュ設定
今回は、この中のリダイレクト設定について徹底的に解剖します。
●一番簡単なリダイレクトをやってみる。
それではまず、一番簡単なリダイレクトをやってみます。
localhost/aaa.html → localhost/bbb.html
にリダイレクトさせてみます。
.htaccessの中身は以下のようになります。
Redirect 301 /index.html /test.html
これで、localhost/index.htmlにアクセスすると、自動的にlocalhost/test.htmlにリダイレクトされます。
まず今のディレクトリ構成
/var/www/
├── .htaccess
├── index.html
└── test.html
現状ではhtaccessの中身は空です。
これでトップにアクセスすると、index.htmlの内容が表示されます。
「indexです。」
次に、htaccessの中身を以下のように変更します。
Redirect 301 /index.html /test.html
これで、再度トップにアクセスしてみます。
すると即座にhttps://localhost/test.htmlにリダイレクトされます。
「testです。」
これでリダイレクトが成功しました。
ただ、こう思った方もいるのではないでしょう。
「よく見るリダイレクトと違うぞ?」
●よく見るリダイレクトとの違い
よく見るリダイレクトは、以下のような感じです。
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/index.html$
RewriteRule ^(.*)$ /test.html [R=301,L]
これでも同じようにリダイレクトが可能です。
では、なぜこんなに複雑にする必要があるのでしょうか?
●RewriteEngineの利点
RewriteEngineを使う利点は、条件分岐ができる事です。
例えば、以下のようなリダイレクトが可能です。
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
この場合、example.comにアクセスした場合のみ、www.example.comにリダイレクトされます。
ではなぜ、
「Redirect 301 /index.html /test.html」
のやり方はダメで
「RewriteEngine On」
のやり方が主流になっているのでしょう?
それぞれのメリットとデメリットを見ていきましょう。
★Redirect メリット・デメリット ・メリット – シンプルでわかりやすい – 少ない記述量で済む – 基本どのサーバーでも使える
・デメリット
– 条件分岐ができない
– 複雑なリダイレクトには向かない
(A⇒Bのような簡単なリダイレクトしか出来ない)
★RewriteEngine メリット・デメリット ・メリット – 条件分岐ができる – 複雑なリダイレクトが可能 – 時間の設定も出来る
・デメリット
– 記述量が多くなる
– 慣れないとわかりにくい
– サーバーによっては使えない場合がある(mod_rewriteが有効になっている必要がある、モジュールのインストールが必要な場合もある)
このようにそれぞれにメリット・デメリットがありますが、複雑なリダイレクトを行う場合はRewriteEngineを使うのが一般的です。
今は簡単なA⇒Bのリダイレクトでも、将来的に複雑なリダイレクトが必要になる可能性もあるので
最初からRewriteEngineを使った方がいいよね?
という考え方が主流になっています。
●RewriteEngineの基本構文
RewriteEngineの基本構文は以下の通りです。
RewriteEngine On
RewriteCond 条件
RewriteRule パターン 置換 [フラグ]
まず、
「RewriteEngine On」にする事でRewriteEngineを使えるようにします。
次に「RewriteCond」で条件を指定します。
条件とは、時間を指定したり、ディレクトリを指定したり、ホスト名を指定したりする事ができます。
最後に「RewriteRule」でリダイレクトのパターンと置換先を指定します。
と、説明を文字で見てもわかりづらいので、実際にやってみましょう。
●A⇒Bのリダイレクトをやってみる
A⇒Bのリダイレクトを「RewriteRule」で書いてみます。
RewriteEngine On
RewriteRule ^index\.html$ /test.html [R=301,L]
これで、localhost/index.htmlにアクセスすると、localhost/test.htmlにリダイレクトされます。
実際にアクセスしてみましょう。
すると、即座にhttps://localhost/test.htmlにリダイレクトされます。
●もし、サーバーにmod_rewriteがインストールされていない場合
サーバーにmod_rewriteのモジュールがインストールされていない場合に、.htaccessに以下を書いてアクセスすると
RewriteEngine On
RewriteRule ^index\.html$ /test.html [R=301,L]
どうなるでしょう?
500 Internal Server Error
となります。
これは、mod_rewriteがインストールされていないために発生するエラーです。
ただ、基本はどのサーバーでもmod_rewriteはインストールされているので、あまり気にしなくても大丈夫です。
● [R=301,L]ってなに?
RewriteのRuleの後ろにかならずつく[R=301,L]とはなんでしょう?
[R=301,L]はフラグと呼ばれるもので、リダイレクトの動作を指定します。
[R=301,L]の意味は以下の通りです。
R=301 : 301リダイレクト(永久的なリダイレクト)を指定します。
L : このルールが最後であることを示します。これ以降のルールは無視されます。
例えば、以下のように複数のRewriteRuleがある場合
RewriteEngine On
RewriteRule ^index\.html$ /test.html [R=301,L]
RewriteRule ^test\.html$ /final.html [R=301,L]
最初のRewriteRuleでindex.htmlにアクセスした場合、test.htmlにリダイレクトされますが、Lフラグがあるため、2つ目のRewriteRuleは無視されます。
したがって、最終的にはtest.htmlにリダイレクトされます。
「L」が付いたら、リダイレクトは終わり!!
と覚えて
「R]はリダイレクトの種類!!
と覚えましょう。
[R=301,L]
つまりこれの意味は
リダイレクトは301,ここで終わりね!
という意味。
●条件を指定してみる
今度はリダイレクトに条件を指定してみましょう。
条件の指定はRewriteCondで行います。
例えば、特定のホスト名にアクセスした場合のみリダイレクトする場合は以下のようになります。
RewriteEngine On
RewriteCond %{HTTP_HOST} ^localhost$ [NC]
RewriteRule ^(.*)$ https://www.localhost/$1 [R=301,L]
この場合、localhostにアクセスした場合のみ、www.localhostにリダイレクトされます。
さて、またわからない単語が出てきましたね。
RewriteCondはリダイレクトの条件を指定するためのものです。
RewriteCond %{HTTP_HOST} ^localhost$ [NC]
この場合、HTTP_HOSTがlocalhostの場合にのみ、次のRewriteRuleが適用されます。
[NC]はNo Caseの略で、大文字・小文字を区別しないことを意味します。
つまり、localhostでもLOCALHOSTでも同じ扱いになるという事です。
覚えにくいですが
[NC]
はノーケース
大文字小文字区別しないよ!
と覚えましょう。
●応用編:特定の時間帯だけリダイレクトする
RewriteEngine On
RewriteCond %{TIME_HOUR} ^(08|09|10|11)$
RewriteRule ^(.*)$ /morning.html [R=302,L]
この場合、午前8時から11時の間にアクセスした場合のみ、morning.htmlにリダイレクトされます。
ちなみに今回は[R=302,L]としていますが、302リダイレクトは一時的なリダイレクトを意味します。
テスト時は302とし、本番で301に変更するのが一般的です。
●疑問:「RewriteEngine On」は必要か?
RewriteEngine Onは毎回書く必要があるのだろうか?
試しに、以下でテスト
元は
RewriteEngine On
RewriteRule ^index\.html$ /test.html [R=301,L]
こうだったが、「RewriteEngine On」なしだと動くか検証してみる。
RewriteRule ^index\.html$ /test.html [R=301,L]
にアクセス
すると、やはりリダイレクトしない。
つまり、「RewriteEngine On」は必須のようだ。
まとめると、リダイレクトは
「RewriteEngine On」
から始まり
[L]で終わる。

コメント