follow us in feedly
Server

.htaccessによるURL書き換え(転送)

サイトを運営していると一部のページのURLを変更したり、あるいはサイト全体を別ドメインに移行(引っ越し)したりすることがあります。その場合に利用すると便利な.htaccess(ドットエイチティアクセス)によるURL書き換え(転送)の基本的な記述を確認してみましょう。

2019年6月19日

書き換え(転送)の基本形

.htaccessによるURLの書き換え(URL転送)の基本的な書き方は以下のようになります。RewriteCondの行に書き換えの条件を記述し、これに該当する場合はRewriteRuleに書かれたルールに従ってURLを書き換えることになります。

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond 書き換えの条件
RewriteRule 書き換えのルール
</IfModule>

ディレクトリー構成が同じ場合

以下のようにディレクトリー構成が同じでドメイン(ホスト名)だけが変わる場合を見てきましょう。サイトを丸ごと別ドメインに変更する場合などです。

https://lindzay.co.jp/contact/
https://lindzay.co.jp/message/
・
・
↓転送
https://chunk.jp/contact/
https://chunk.jp/message/
・
・	

.htaccessの記述はこの場合は以下のようになります。

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^lindzay\.co\.jp [NC]
RewriteRule ^(.*) https://chunk.jp/$1 [R=301,L]
</IfModule>

RewriteCondの行が条件になりますが、この場合は「ホスト名{HTTP_HOST}がlindzay.co.jpの場合は」となります。正規表現ですので「^」は行頭、「\」はエスケイプになります。正規表現では「.(ドット)」は任意の一文字(改行を除く)を意味しますが(メタ文字)、この場合はそのまま「.(ドット)」という文字(リテラル)として解釈させたいのでエスケイプしています。
 RewriteRuleの行は書き換えのルールになりますが、この場合はhttps://chunk.jpに転送しつつ、「その後ろに付いている文字列をそのままhttps://chunk.jp/の後ろにくっつける」となっています。^(.*)の部分はhttps://lindzay.co.jp/より後の部分の文字列を指します。例えばhttps://lindzay.co.jp/contact/であればcontact/の部分です。そしてこの部分を()でくくることで(キャプチャ)、これを$1で呼び出しています(後方参照)。正規表現では「*」が0以上の繰り返し(量指定子)を意味しますので任意の一文字が0以上繰り返されたものとなりますので「.*」は特に制限のない任意の文字列となります。つまり、「https://lindzay.co.jp/の後についている文字列がなんであれ、この部分を転送先のURLの末尾にそのままくっつけないさい」となっているわけです。この結果としてhttps://lindzay.co.jp/contact/がhttps://chunk.jp/contact/に。https://lindzay.co.jp/message/がhttps://chunk.jp/message/に書き換えられます。ちなみに[NC]は大文字小文字を区別しない。[R=301]は恒久的なリダイレクト(=サイトの移転)。[L]は処理の終了をそれぞれ意味します。
エディタで学ぶ正規表現入門 (全18回) – プログラミングならドットインストール

特定のページだけを書き換える場合(クエリー無し)

下記のように特定のページを同一ドメイン内の別のページに書き換える場合を考えてみましょう。ワードプレスで特定の投稿スラッグを変更した場合などです。

https://lindzay.co.jp/contact/
↓転送
https://lindzay.co.jp/inquiry/

この場合はRewriteRuleに書き換えのルールを書けばOKでしょう。^contact/?$をinquiry/に書き換えるというシンプルな記述になります。正規表現において「?」は0以上1以下繰り返し(量指定子)、「$」は末尾を表します。つまり「contactまたはcontact/でアクセスされた場合はinquiry/に書き換える」となります。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^contact/?$ inquiry/ [R=301,L]
</IfModule>

また特定のページを別ドメインのページに書き換えたい場合は以下のように書けます。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^contact/?$ https://chunk.jp/inquiry/ [R=301,L]
</IfModule>

特定のページだけを書き換える場合(クエリー有り)

前述のケースと同じく同一ドメインの書き換えの場合でも、クエリーが付く場合は少し書き方が変わります。ワードプレスのパーマリンク設定を基本から投稿名などに変更する場合です。以下のようなケースを考えてみましょう。

https://chunk.jp/?page_id=250
↓転送
https://chunk.jp/contact/

RewriteCondの行は書き換えの条件ですがこの場合は「クエリー{QUERY_STRING}がpage_id=250の場合は」となります。最後に$を付けましたが$は正規表現で行末を意味しますので、page_id=2500やpage_id=2501などを除外するため念のためつけておきました。
 RewriteRuleは書き換えのルールですが、.htaccessの場合はホスト名の後の「/」は無視するので、「^$」の書き方はルートディレクトリを表すことになります。したがって/(ルート)以下の部分がcontact/に書き換えられクエリーは削除されます。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} page_id=250$
RewriteRule ^$ contact/ [R=301,L]
</IfModule>

ちなみに4行目をRewriteRule ^(.*) contact/ [R=301,L]といった書き方にするとcontact/?page_id=250に書き換えられ、その結果再度3行目の条件が該当し・・・無限ループになりますのでご注意ください。

https、www無しに統一

さくらインターネットの場合はマニュアルページにも書いてありますが、以下のような記述になります。ここまでの内容が理解できている方は問題無くおわかりになるかと思います。5行目が一瞬わかりづらいかもしれませんが、ここは条件を書くところなので「https通信がoffになっていたら」となります。6行目は{HTTP_HOST}と{REQUEST_URI}という変数を使用して汎用的な記述となっていますので、ホスト名などを具体的に入れて書くこともできます。
.htaccessによるアクセス制御 – さくらのサポート情報 常時SSL化したWordPressのドメイン名を統一させたい

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.jp) [NC]
RewriteRule ^(.*) https://example.jp/$1 [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

ワードプレスデフォルトの記述

最後にワードプレスをインストールすると.htaccessに必ず記述される以下の記述を見てみましょう。1つ目のルールが5行目に書かれています。これは「index.phpにアクセスがあった場合は何もせずに(書き換えを行わずに)処理を停止する」と書かれています。
 2つ目のルールが分かりづらいですが、6行目は「ファイルが存在しない場合は」、7行目は「ディレクトリが存在しない場合は」という意味になります。例えば「https://chunk.jp/abc/というアクセスがあった場合、abcというディレクトリが無かったら8行目のルールを実行せよ」となります。実際にワードプレスをインストールしたディレクトリーにabcというディレクトリーを作ってindex.htmlを置いてみるとhttps://chunk.jp/abc/でindex.htmlが表示されるはずです。これは7行目の条件が該当しないので、8行目の書き換えが実行されていないわけです。逆に6行目も7行目も該当する場合は8行目のルールが実行され、全てのアクセスがindex.phpに振り分けられます。振り分けられたことで再度5行目の条件に該当し書き換えが終了します。つまり5行目は無限ループを防いでいるということになります。ワードプレスの場合は一旦index.phpにアクセスを集約し、内部的にパーマリンクを構築(リライト)しているのでこのような記述になっています。

# 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

以上で「.htaccessによるURL書き換え(転送)」の解説を終わります。

このエントリーをはてなブックマークに追加