mod_rewriteを使ってのリダイレクト設定

青葉城
※D700+TAM DiSP 90mm (272E)

WPへの移行にあわせてドメインも移転した。検索エンジンの結果で表示されるページのURLが変更されるため、サーバー サイドの301リダイレクトを使用してリダイレクト設定をおこなった。301ステータスコードはページが新しいサイトへ移動したことを意味するので、これで検索エンジンが移転先のページにたどり着くことが保証される。ちょっとしたSEO対策にもなるので、忘れないうちにメモしておこう。

■基本のリダイレクト – 「Redirect permanent」を使う301リダイレクト設定
基本的に301リダイレクトは、以下の書式で.htaccessファイルに記述すれば可能だ。
ただ、試行の結果、この方法ではボクの目的を遂げることはできないことがわかったので、今回の移行では使っていない。

Redirect 301 /oldblog http://example.com/newblog

もしくは、

Redirect permanent /oldblog http://example.com/newblog

2つの構文はどちらも同じ意味であり、「/oldblog 」がリダイレクト元、「http://example.com/newblog 」がリダイレクト先である。
ちょっと紛らわしいかもしれないが、リダイレクト元はURLのルートからのパスを記述する(サーバーの物理的なフルパスなどではなく、大雑把に言うならURLからドメイン名を省略したもの)。そして、リダイレクト先には「http://~」といったURL全体を記述する。
後者の構文では「permanent」のくだりが「301(完全な移動)」であることを伝えてくれるステータスになる。「permanent」がなく「Redirect」のみだと、検索エンジンには「302(一時的な移動)」と解釈されてしまうので、サイトの移転など二度と戻る可能性がない場合は必ず「permanent」を記述するようにする。

参考:
301リダイレクト

■mod_rewriteを使っての301リダイレクト設定
ボクが今回使ったリダイレクトがこの方法だ。前述のRedirect permanentを使う方法では、クエリ付きの動的なページは、うまく動作してくれなかった。クエリとは、サーバーに渡す値や文字列データを指定するための「?」の後にある引数やその数値のことで、クエリを用いた動的なページとは”aaa.php?id=01”などのようなページリンクのことである。
他の方法を探していたところ「Rewrite」を使う方法が見つかったのではあるが、このRewriteで使われる正規表現がややこしい。一つ試しては失敗、また違うものを試しては失敗・・・・といった試行錯誤をしばらく繰り返していた。
そんなこんなだったが、こんなボクでもようやくRewriteの使い方が理解できてきたのでメモしておくことにする。

ボクがしたかったのは、
[text gutter="false"]
1.サブディレクトリを変更
2.拡張子のphpは取り除く
3.アンダースコアが含まれる場合、ハイフンに変更
4.日付アーカイブの場合にはパスを変更
[/text]
といったリダイレクトである。
つまり、こういうことだ。

http://from_example.com/blog/archives/2010/09/post_123.php

http://to_example.com/blog/2010/09/post-123/

http://from_example.com/blog/archives/2010/09/

http://to_example.com/blog/2010/09/

試行錯誤の末、以下のように .htaccess を記述することで意図した通りのリダイレクトを実現できた。もっとスマートな方法はあるとは思うけど、とりあえずは問題もなさそうである。
[php num=1 font_size="60%"]
RewriteEngine on
RewriteBase /blog/archives/
RewriteRule ^([0-9]+/)([0-9]+/)([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^_]+)\.php$ http://to_example.com/blog/$1/$2/$3-$4-$5-$6-$7/ [NC,R=301,L]
RewriteRule ^([0-9]+/)([0-9]+/)([^_]+)_([^_]+)_([^_]+)_([^_]+)\.php$ http://to_example.com/blog/$1/$2/$3-$4-$5-$6/ [NC,R=301,L]
RewriteRule ^([0-9]+/)([0-9]+/)([^_]+)_([^_]+)_([^_]+)\.php$ http://to_example.com/blog/$1/$2/$3-$4-$5/ [NC,R=301,L]
RewriteRule ^([0-9]+/)([0-9]+/)([^_]+)_([^_]+)\.php$ http://to_example.com/blog/$1/$2/$3-$4/ [NC,R=301,L]
RewriteRule ^([0-9]+/)([0-9]+/)$ http://to_example.com/blog/$1/$2/ [NC,R=301,L]
RewriteRule ^(.*)\.php$ http://to_example.com/blog/$1/ [NC,R=301,L]
[/php]
この.htaccessファイルを、転送元サーバ(旧サーバー)上の2行目で指定した場所「/blog/archives/」に置く。
1行目: RewriteEngine on は、URLの書き替えができるようにRewrite機能をOnする。
2行目: RewriteBase は書き替えのベースとなるパスを指定する。後述するRewriteRuleは、ここで指定するパスで補完されることになる。なお、3行目のところで説明するが、ドキュメントルートの場合にはRewriteBaseの記述は不要だ。
3行目~6行目: この正規表現がポイント。一番シンプルな6行目を使って説明する。
RewriteRule ^([0-9]+/)([0-9]+/)([^_]+)_([^_]+)\.php$ http://to_example.com/$1/$2/$3-$4/ [NC,R=301,L]
^と$で囲まれた間がリダイレクト元のパターンを表す部分で、^が行頭、$が行末を意味する。()で囲まれている4つそれぞれが後方参照で、()はその選択範囲の境界を明示するもの。このケースでは左から順に$1~$4という後方参照が割り当てられる。
([0-9]+/)は ”一つ以上の0から9の数字列” 、そしてそれに続く"/"を意味するので、「2010/」や「12/」などの年月がここに該当する。
([^_]+)は、"_"(アンダースコア)以外の1文字以上の文字列という意味で、「post」や「123」が該当。
そして、”\.”は、正規表現の特殊文字ではなくて単なるピリオドであるという意味だ。つまりこの6行目は「2010/09/post_123.php」といったリクエストがマッチする。これにRewriteBaseで記述したパス"/"が先頭に補完されるので、「/blog/archives/2010/09/post_123.php」というリクエストに対応することになる。
ここで注意しなければいけないのは、ドキュメントルートである場合だ。「RewriteBase /」などと指定していると、「/」がさらに補完されてしまうので「http://from_example.com//blog/2010/09/post_123.php」というリクエストになってしまう。そのため、ドキュメントルートの場合には RewriteBase の記述は不要である。
リダイレクト先についてはURL全体を記述する。1つ目の後方参照である$1のところには、先に説明した一番最初(左端)の([0-9]+)の部分である「2010」などが入る。$2には左から2番目が、$3は3番目が・・・・といった具合。そして、$3と$4の間にはアンダースコア(_)の代わりに”-”(ハイフン)を挿入している。つまり先のリクエストは、RedirectBaseで補完されていた部分が破棄されて「http://to_example.com/blog/2010/09/post-123/」というリクエストに書き換わる。
最後のオプションは、「NC」でパターンについて大文字・小文字を区別しない(NoCase)、「R=301」で301リダイレクトを指定、「L」は書き換えが行われたら終了 (Last) にするため。現在の書き換え後のURLが後続のルールによってそれ以上書き換えられることを防止するものだ。
ハイフンが複数含まれるリクエストを考慮し、同じ考え方でハイフン4つまでのルールを作成した。
7行目: 同じ考え方で日付アーカイブのパターンにも対応。「/blog/archives/2010/09/」のリクエストは、「http://to_example.com/blog/2010/09/」に書き換わる。
8行目: 前述のパターンに該当しないものは全て、ドメインだけ変えてリダイレクトする。

-------------------------------
もうひとつの、動的クエリを使ったページの301リダイレクトについては、以下のような.htaccessを作成。
[php num=1 font_size="60%"]
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^id=(.*)$
RewriteRule ^oldblog/index.php$ http://to_example.com/newblog/%1.html? [NC,R=301,L]
[/php]
これで、例えば”http://from_example.com/oldblog/index.php?id=01”というリクエストは、”http://to_example.com/newblog/01.html”にリダイレクトされるようになる。
1行目: RewriteEngine on で、URLの書き替えができるようにRewrite機能をOn
2行目: RewriteBase は書き替えのベースとなるパスを指定
3行目: RewriteCond はクエリ部分のパターンを指定。引数は「id=」とそのまま表記し、(.*)で後方参照とする。
4行目: RewriteRule でパターンにマッチした場合の書き換えルールを指定する。
「^oldblog/index.php$」がリダイレクト元であり、RewriteBaseで指定したパスが自動的に補完されるので、この場合は「http://from_example.com/oldblog/index.php」がリクエストパスとなる。
「https://rightdice.com/newblog/%1.html?」がリダイレクト先であり、URL全体を記載する。「%1」のところにはRewriteCondで処理した後方参照(クエリ部分)である(.*)の内容が入るので。リクエストは「https://rightdice.com/newblog/index.html?id=1」などとなる。そして、最後の「R=301」で301リダイレクトを指定している。

参考:
「URLの書き換え Rewrite」
mod_rewrite URLを書き換えるApacheモジュール
「rewriteモジュールでURLを書き換えろ!」

タイトルとURLをコピーしました