独自ドメインの「www あり」「www なし」統一の必要性について書きましたが、301 リダイレクトを設定するには、いくつかの方法があります。Apache と pound を使った方法をまとめておきます。

Apache: .htaccess に RewriteRule を書く方法

レンタルサーバで、.htaccess が設置可能な場合に取る方法です。

www ありに統一

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(example.com)(:80)? [NC]
RewriteRule ^(.*) http://www.example.com/$1 [R=301,L]

www なしに統一

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.example.com)(:80)? [NC]
RewriteRule ^(.*) http://example.com/$1 [R=301,L]

Apache: httpd.conf に追加のバーチャルホストとして記述する方法

Apache サーバ全体の管理者権限を持っている場合に使う方法です。

www ありに統一

NameVirtualHost *:80

<VirtualHost *:80>
ServerName example.com
Redirect permanent / http://www.example.com/
</VirtualHost>

www なしに統一

NameVirtualHost *:80

<VirtualHost *:80>
ServerName www.example.com
Redirect permanent / http://example.com/
</VirtualHost>

PHP コードを書く方法

PHP が利用可能な環境で、ページ単位で 301 リダイレクトするのに適した方法です。

www ありに統一

<?php
header("HTTP/1.0 301 Moved Permanently");
header("Location: http://www.example.com/");
?>

www なしに統一

<?php
header("HTTP/1.0 301 Moved Permanently");
header("Location: http://example.com/");
?>

pound を使った方法

以前紹介した pound というリバースプロキシサーバを使えば、Apache 側に何の設定もしなくても、pound 側でリダイレクトすることが可能です。

www ありに統一

ListenHTTP
Address 192.168.0.1
Port 80
Service
HeadRequire "Host: www.example.com.*"
BackEnd
Address 192.168.0.2
Port 80
End
End
Service
HeadRequire "Host: example.com.*"
Redirect "http://www.example.com/"
End

www なしに統一

ListenHTTP
Address 192.168.0.2
Port 80
Service
HeadRequire "Host: example.com.*"
BackEnd
Address 192.168.0.3
Port 80
End
End
Service
HeadRequire "Host: www.example.com.*"
Redirect "http://example.com/"
End

pound 背後で Apache 301 リダイレクトは無限ループになる

ところが、pound には落とし穴があります。Apache の管理をしなれた人だと、Apache 側でリダイレクトすればいろいろ細かい設定ができて良いのでは? と思いますね。

pound 側は、以下のように 2つのバーチャルホストへのリクエストを同一 Apache サーバに転送するように設定しておき、

ListenHTTP
Address 192.168.0.2
Port 80
Service
HeadRequire "Host: www.example.com.*"
BackEnd
Address 192.168.0.3
Port 80
End
End
Service
HeadRequire "Host: example.com.*"
BackEnd
Address 192.168.0.3
Port 80
End
End
End

転送された Apache 側で、.htaccesshttpd.conf にリダイレクト設定を施しておいたとします。

一見うまくいきそうですが、私が試した限りでは無限ループになってしまいました。あくまで pound を入れた以上は、pound 側でリダイレクトを取り仕切るしかなさそうです。