.htaccess mod_rewriteによる正規表現を使ったリダイレクト設定
.htaccessのリダイレクトはmod_rewrite構文による正規表現を使った非常に便利な機能です。特定ページやディレクトリ階層へと転送できます。
301リダイレクトで転送元の価値をそのまま転送先へ継承する事ができますのでSEO・url正規化によく利用されます。
mod_rewrite構文でよく見かける正規表現記号や後方参照については、コピペで済まさずにきちんと理解しておきましょう。
mod_rewriteによるリダイレクト構文
.htaccessでリダイレクトを掛ける場合、.htaccessではmod_rewrite機能を実行しています。
mod_rewriteとは
mod_rewriteとはWEBサーバーApacheのモジュールの一つで、さまざまな条件を指定してURL書き換えができる機能です。
命令数に制限はないですし、正規表現を使ってURLの書き換えができるため多彩な処理が行えます。
本来はhttp.confファイルにて設定をする機能なのですが、htaccessファイルでも設定ができる事を利用しているのですね。
mod_rewriteはその用途に応じて主に以下の3種類がよく利用されます。
Redirect機能
リダイレクトをさせる転送元を明確に指定して、その指定されたディレクトリ・ページなどを全て転送させる命令です。
RedirectMatch機能
「正規表現」を利用して、ファイルの種類や基点などの条件を指定して、対象に含まれるものを転送させる命令です。
Rewrite機能
環境変数を利用した複雑な指定ができ、アクセスされたパス以外の条件を参照する事もできるようになります。
「正規表現」を利用してファイルの種類やトリガー条件を指定し、対象に含まれたものを転送させる命令です。
mod_rewrite機能一覧
.htaccessでよく見かけるmod_rewrite機能の命令をご紹介します。
RewriteEngine on RewriteBase / RewriteCond RewriteRule
・RewriteEngine on
RewriteEngineは、Apacheのモジュールであるmod_Rewrite機能を有効にするか・無効にするかの宣言部分です。
ON:有効
OFF:無効
・RewriteBase /
「Rewrite機能」のベースパスを指定します。基本は「/」ですね。
・RewriteCond
RewriteCondはURLを書き換える条件となる構文です。
環境変数を使用する事ができるので、多くの要素を実行の条件にする事ができます。
PC・スマホなどユーザーエージェントの判定なども一般的にこの機能が利用されます。
・RewriteRule
条件を満たしたときに実行される実行命令の内容が記載されます。
mod_rewriteそれぞれの実行事例
Redirectを利用した具体的事例
/test/以下のディレクトリを全て「http://example.com/~」へリダイレクトする場合
Redirect permanent /test/ https://example.com/
RedirectMatchを利用した具体的事例
全てのGIFファイルを別サーバーにある同名のJPEGファイルにリダイレクトする場合
RedirectMatch (.*)¥.gif$ https://example.com$1.jpg
全てのGIF・JPEG・PNGファイルを別サーバにある同名の画像ファイルにリダイレクトする場合
RedirectMatch 301 (.*)¥.(jpg|jpeg|gif|png)$ https://example.com$1.$2
RewriteRuleを使ったユーザーエージェントによる振り分け例
PC・スマホサイトの振り分け
RewriteEngine on RewriteBase / RewriteCond %{REQUEST_URI} !/sp/ RewriteCond %{HTTP_USER_AGENT} (iPod|iPhone|Android.*Mobile|Windows¥ Phone) RewriteRule ^(.*)$ sp/$1 [R] RewriteCond %{REQUEST_URI} /sp/ RewriteCond %{HTTP_USER_AGENT} !(iPod|iPhone|Android.*Mobile|Windows¥ Phone) RewriteRule ^sp/(.*)$ $1 [R]
上記の場合スマートフォンでPCサイトアクセスすると「/sp/」ディレクトリにリダイレクトします。
逆にPCでスマホサイト「/sp/」にアクセスをすると、PC向けのトップディレクトリに転送される事になります。
正規表現について
RewriteCondやRewriteRuleなどでよく使われる正規表現を表にまとめています。
テキスト | |
---|---|
. | 任意の1文字 |
[文字] | いずれかの1文字 [abe]ではa,b,cいずれかの1文字 [a-z]では、aからzまでアルファベットの小文字で1文字 [-A-Z]では、「-」という文字あるいはアルファベットの大文字で1文字 [-0-9a-zA-Z]では、「-」という文字あるいは0から9、あるいはアルファベットの小文字か大文字でいずれか1文字 |
[^文字] | これら以外の1文字 [^abcd]は、a,b,c,d以外の1文字 [^0-9]は、数字以外の1文字 |
文字列1|文字列2 | 文字列1もしくは文字列2 |
(文字列) |
グループ化(選択肢の境界設定、後方参照のために使用する) 一般的に (.*) のように使われる |
^ | 行頭(文字位置の指定) |
$ | 行末(文字位置の指定) |
¥文字 | エスケープ処理:通常の文字として扱う 「.」は任意の1文字を表現する正規表現「.」と間違うので、例えば画像の場合は\.jpgと表記する |
- | 置換を禁止する アクセス禁止の時などに使用 |
! | パターンの前に用いる事でパターンを否定する命令 |
「^」や「$」や「(.*)」について
表の中で行くと「^」や「$」や「(.*)」などは最もよく使われる表記です。
上記はよく.htacessで見たことがあるのではないでしょうか。あれって何を示しているの?と思う方もいると思います。
詳しく解説をしましょう
例えば「https://aaa.com/bbb.html」にアクセスをしたとしましょう。
RewriteEngine On RewriteRule ^(.*)$ abc/$1
この場合https://aaa.com/abc/bbb.htmlへリダイレクトされます。
この時RewriteRuleの($1)部分には、「bbb.html」が入ります。
各記号の見方
(.*)は厳密には、^(.*)$ でひとくくりです。「^」の部分が行頭、「$」の部分が行末を示しています。
その中にある「.*」はあらゆる文字列が対象となる表現です。なので(.*)は全ての文字列を受け入れる事を意味します。
これにより「^(.*)$」は「bbb.html」を受け入れる事になり、bbb.htmlが「$1」の部分へと後方参照されます。
つまりここで「abc/$1」とは「abc/bbb.html」を示す事になるのですね
実行結果
結果「https://aaa.com/bbb.html」にアクセスがあった場合、https://aaa.com/abc/bbb.htmlが表示されるようになるのです。
この時もし仮に、https://aaa.com/gagaga.html にアクセスしたとしたら、gagaga.htmlが$1に入ります。
https://aaa.com/gagaga.html にアクセスがあった時は
https://aaa.com/abc/gagaga.htmlへリダイレクトされます。
^(.*)$ の表記は「どんなファイル名でも」という意味だと認識しておいてください。
後方参照について
上で後方参照という言葉が出てきました。
これはわかりやすく言うと、()で囲まれた部分を、後に出てくる実行命令で参照するという意味です。
もう一つの例で後方参照をみていきましょう
例えば「https://aaa.com/abc/bbb.html」にアクセスがあったとしましょう。
RewriteEngine On RewriteRule ^.*/(.*)$ ccc/$1
上記の様に書かれていたとします。
この時RewriteRuleの条件対象は「abc/bbb.html」です。
「.*」には「abc」の部分、「(.*)」には「bbb.html」が入ります。
このとき()の間は全ての内容を受け入れる事になるのでどんなファイル名でもOKでしたね。
ですので$1という形でbbb.htmlが後ろに引き渡されます。これが後方参照です。
なんでも後ろに渡す部分と渡さない部分
つまり「ccc/$1」の部分が「ccc/bbb.html」となります。
よって「https://aaa.com/abc/bbb.html」にアクセスがあった場合、「https://aaa.com/ccc/bbb.html」のファイルを表示されるようになるのです。
ポイント
※一つ目の「.*」は「()」で囲まれていないので後方参照はされません。
※二つ目の「.*」は「()」で囲まれているので「$1」部分に後方参照されます。
つまりabcの部分はどのようなディレクトリでも良いのですが、「転送先には絡まない」事を意味しています。
https://aaa.com/def/gagaga.html にアクセスがあった時は
https://aaa.com/ccc/gagaga.htmlへリダイレクトされます。
表示されているコード「\」について
よく下記のhtaccessコードが貼り付けてあるのを、WEBページで見かけませんか。
RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.example\.com RewriteRule ^(.*) http://example.com/$1 [R=301,L]
上記はwww付きのアドレスをwwwなしのアドレスに飛ばすリダイレクト設定です。
ここでwww.example.comの「.」ドットの前に斜め線「\」がそれぞれ2つありますよね。
これはWEBページでの表示の際に「斜め線」に見えていますが、実際は「¥」マークです。
¥は「.」が.jpgや.htmlなどの拡張子のドットである事を示す
¥マークはエスケープ記号と呼ばれるものです。
その後の「.」ドットを正規表現ではなく「拡張子」として認識するためにわざと入れられている記号なのです。
直後のドットを機能させるためだけに入っている裏方さんなのです。
WEBページ上では半角の¥を表示できない
ところが皮肉な事に、WEBページ上では仕様としてこの半角の¥マークをそのまま「¥」として表示させる事はできない様になっています。
なので見た目上、斜め線「\」に置き換えられているのです。
実際にPC上のファイルにコピーして貼り付けてみると、.htaccessのファイル上では斜め線の部分がきちんと「¥」になっているのがわかると思います。
何の気なしにコピペしていると気づかないかも知れませんが、WEBページ上で表記されている斜め線は「¥」が文字化けしていると思っておきましょう。
¥マークをWEB上で表示させるには
ちなみにWEBページ上でもきちんと「¥」を見せようと思ったら、& y e n ;と表記する必要がありますね。
※& y e n ;は半角スペースを入れて、コードを直接表示しています。
私はなるべく気を付けてそう表記しています(htmlソースを見れば確認できますよ)。
一応知ってて当然の情報ですし、コピペすればきちんと¥マークになるので、あえて何もせずに斜め線のまま掲載している人が多いと思います。
あえて¥をWEBページで表示した例
RewriteEngine On RewriteCond %{HTTP_HOST} ^www¥.example¥.com RewriteRule ^(.*) http://example.com/$1 [R=301,L]
ソース上では& y e n ;になっています。
301リダイレクト・302リダイレクト
具体的な設定方法をご紹介する前に「301・302」のリダイレクトについて説明しておきましょう。
301リダイレクト
301リダイレクトは最も一般的なWEBページの転送方法であり、永続的な転送を意味しています。
この301リダイレクトにより、転送元ページが持っていた全ての評価を転送先のページへと引き継ぐことができます。
SEOの評価継承・リンクポピュラリティのためには必須です。
302リダイレクト
それに対して302リダイレクトというものもあり、こちらは一時的な転送を意味しています。
301リダイレクトと302リダイレクトの違い
・301リダイレクト:永続的な転送で評価の引継ぎが行われ、Googleの対応が速い
・302リダイレクト:一時的な転送で評価引継ぎが行われるが、301と比べてGoogleの対応が遅い
本記事で紹介している転送は、全て「301リダイレクト」による転送方法を紹介しています。
特定ページのリダイレクト記述
該当する特定のページのURLを変更した場合やを削除した時などに設定します。
「aaa.html」から「bbb.html」に転送する場合
RewriteEngine on RewriteRule ^aaa.html$ https://www.example.com/bbb.html [L,R=301]
「aaa.html」から「aaa/index.html」に転送する場合
RewriteEngine on RewriteRule ^aaa.html$ https://www.example.com/aaa/index.html [L,R=301]
特定ディレクトリ・階層のリダイレクト記述
ページ単位ではなく、ディレクトリや階層を変更したい場合の設定になります。
「/up_content/」ディレクトリを「/down_content/」に変更する場合
RewriteEngine on RewriteRule ^up_content(.*)$ https://www.aaa.com/down_content$1 [L,R=301]
全て別ドメインへリダイレクトさせる場合
やむを得ない事情でドメイン自体を変更なければならない場合に使います(お勧めはしません)。
この時下層ページのURLも全て揃える必要があります。違う箇所があればそれぞれ別途設定が必要になります。
「https://www.aaa.com/」から「https://www.bbb.com/」に転送する場合
RewriteEngine On RewriteCond %{http_host} ^www.aaa.com RewriteRule ^(.*) https://www.bbb.com/$1 [R=301,L]
URL正規化をするリダイレクト設定
正規化は「Googleに評価してもらうURLを統一すること」でリンクポピュラリティを集約する、SEO的な設定になります。
「www.なし」のURLを「www.あり」に転送する場合
RewriteEngine on RewriteCond %{ HTTP_HOST} ^aaa.com RewriteRule ^(.*)$ https://www.aaa.com/$1 [L,R=301]
「index.htmlあり」のURLを「index.htmlなし」に転送する場合
RewriteEngine on RewriteCond %{THE_REQUEST} ^.*/index.html RewriteRule ^(.*)index.html$ https://www.aaa.com/$1 [L,R=301]
SSL化(http⇒https)への転送
RewriteEngine on RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://www.aaa.com/$1 [L,R=301]
あわせて読みたい関連記事
404エラー時のリダイレクト設定
ページが存在しなかったら「404エラーページ」へ飛ばす
ErrorDocument 404 /404.html
上記で転送する場合は、事前に「404.html」というファイルを作成してアップロードしておきましょう。
ファイル名(404.html)はこの名前でなくても構いません。
ページが存在しなかったら「TOPページ」へ飛ばす
ErrorDocument 404 https://www.aaa.com/
htaccessリダイレクト:Wordpressの場合
基本的な記述の仕方はhtmlと変わりません。TOPディレクトリにある.htacessの中に記述します。
初期状態のhtaccess内記述
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index¥.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
.htacess上にリダイレクト分を書く場合、上記の構文はそのまま触らずにこの構文よりも上に書くようにしましょう(最上段の#BEGIN WordPressよりも上に書きましょう。)。
上記構文より下や中に書かない様にして下さいね。
各URLの終わりが「/」であり、特定の拡張子が付かない場合
a-pageからb-pageへのリダイレクト
<IfModule mod_rewrite.c> RewriteRule ^a-page/$ b-page/ [R=301,L] </IfModule>
通常は上記の様に「/」でページURLが終わる事が多いですよね。その場合は上の様にします。
各URLに「/」自体がない場合
a-pageからb-pageへのリダイレクト
<IfModule mod_rewrite.c> RewriteRule ^a-page$ b-page [R=301,L] </IfModule>
「/」が付かないURLの場合です。いずれも元々あった構文よりも上に書きましょう。