完全ガイド:.htaccessリダイレクトの基本と運用—301/302/307/308の意味、mod_rewriteとmod_aliasの使い分け、SEOとセキュリティ対策まで

はじめに — .htaccess リダイレクトとは何か

.htaccess(ディレクトリ単位のApache設定ファイル)を使ったリダイレクトは、特定のURLへのアクセスを別のURLへ転送する仕組みです。Webサイトの移行、URL 正規化(canonicalization)、HTTP→HTTPS の強制、古いページから新しいページへの恒久的な移設などで多用されます。リダイレクトはクライアント(ブラウザや検索エンジン)に新しい場所を伝えるため、正しいステータスコード(301, 302, 307, 308 など)を返すことがSEOや動作上重要です。

基本の仕組みと注意点

  • .htaccess の役割:.htaccess は Apache の per-directory 設定ファイルで、ディレクトリ単位で設定を上書きできます。サーバ全体の設定(httpd.conf)に比べて設定を個別に行える利点がある反面、Apache は各リクエストでディレクトリごとに .htaccess の存在をチェックするため、パフォーマンスの悪化要因になります。

  • 有効化条件:.htaccess を利用するには Apache の設定で AllowOverride が適切に設定されている必要があります。無効化されている環境では .htaccess は無視されます。

  • Apache 固有:.htaccess による設定は Apache 特有です。nginx や他のサーバでは別の設定(nginx.conf や server ブロック)で同様のリダイレクトを記述します。

HTTP ステータスコードとその意味

  • 301 Moved Permanently:恒久的な移転。検索エンジンは新しいURLをインデックスするように扱うべきです(SEO上の移行に主に使用)。

  • 302 Found / 307 Temporary Redirect:一時的なリダイレクト。クライアントは元のURLを保持すべきで、将来的に元へ戻ることが期待される場合に使います。HTTP/1.1 では 302 の解釈が曖昧だったため、307 が導入されました(POST などのメソッドが保持される等の差)。

  • 308 Permanent Redirect:301 に似ていますが、リクエストメソッドを保持する点(POST→POST)で 301 と異なります。

代表的な方法:mod_alias(Redirect / RedirectMatch)と mod_rewrite(RewriteRule)

Apache では主に二つのモジュールでリダイレクトを行います。用途に応じて使い分けます。

  • mod_alias(Redirect, RedirectMatch):単純なパスの置換・転送に適しており、書き方もシンプルです。例:

    Redirect 301 /old-page.html /new-page.html
    RedirectMatch 301 ^/old-directory/(.*)$ /new-directory/$1

    Redirect は第1引数にパス、第2引数に移動先、RedirectMatch は正規表現を使えます。

  • mod_rewrite(RewriteEngine, RewriteRule, RewriteCond):非常に柔軟で強力なツール。ホスト名やプロトコル、クエリ文字列、ユーザーエージェントなど様々な条件で制御できます。複雑な正規表現や条件分岐を用いる場合はこちらを使います。例:

    RewriteEngine On
    # www へのリダイレクト(非www → www)
    RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
    RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

.htaccess(mod_rewrite)でよく使うフラグと変数

  • [R=コード]:リダイレクトのHTTPステータスを指定(例 R=301)。省略時は 302。

  • [L]:そのルールがマッチしたらそれ以降のルールを処理しない(最後のルール)という意味。ただし .htaccess の per-directory 処理の文脈での挙動に注意が必要です。

  • [QSA]:既存のクエリ文字列にサブスティテューション側のクエリを追加する。

  • [NE]:エスケープ処理を行わずに非エスケープで出力(特殊文字を%エンコードしない)。

  • 主なサーバ変数:%{HTTP_HOST}, %{REQUEST_URI}, %{REQUEST_FILENAME}, %{QUERY_STRING}, %{HTTPS}("on"/"off")など。

よくある実用的なリダイレクト例(コードと解説)

以下は運用で頻出する例と解説です。WordPress のようなCMSと併用する場合、既存のパーマリンクルールより前に配置することで期待する動作を得ます。

1) HTTP → HTTPS に強制リダイレクト

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

ポイント:HTTPS が off ならリダイレクトします。負荷を低減するため、可能ならサーバ設定(仮想ホスト)で行う方が望ましいです。

2) non-www → www、またはその逆

# non-www → www
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

同様に www から非www へリダイレクトする場合は条件とターゲットを逆にします。

3) 特定ページの恒久的移動(301)

Redirect 301 /old-page.html /new-page.html

単純なパス移動は mod_alias の Redirect が簡潔です。

4) 正規表現で大量のURLを一括変換

RedirectMatch 301 ^/old-section/(.*)$ /new-section/$1

old-section 配下を新しいディレクトリに一括で移動する場合に便利です。

5) クエリ文字列を取り扱う場合(QSA と ? の挙動)

RewriteRule の置換に ? を含めると元のクエリは置換されます。元のクエリを保持して追加したい場合は [QSA] を使います。

# 元のクエリを残して追加
RewriteRule ^old$ /new?added=1 [R=302,QSA,L]

トラブルシューティングとよくある落とし穴

  • ループ(redirect loop):条件が適切に設定されていないと無限リダイレクトになることがあります。RewriteCond でホスト名やスキーム、既にリダイレクト済みかをチェックして回避します。

  • Query string の扱い誤り:サブスティテューションに ? を含めると元のクエリが消えます。必要なら QSA を明示的に使うか、既存クエリを注意深く扱ってください。

  • パフォーマンス:.htaccess は per-request でディレクトリを走査するため、可能ならサーバの main config(httpd.conf)に移すと速くなります。

  • ファイルの存在判定:ファイルやディレクトリが存在する場合のリダイレクト回避は以下のようにします:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ...
  • エスケープと特殊文字:URL の中の +, &, =, % などは意図したとおりに扱われない場合があります。NE フラグや適切なエンコードを検討してください。

WordPress と .htaccess の関係

WordPress は「パーマリンク」のために .htaccess に mod_rewrite ルールを自動で書き込みます(一般的な構成)。独自のリダイレクトを追加する場合は、WordPress が生成するブロック(# BEGIN WordPress / # END WordPress)の外側に記述するか、管理画面でリダイレクトプラグインを使う方法があります。配置順序が重要で、先に評価されるルールにより挙動が変わるため、カスタムリダイレクトは WordPress ブロックより上に置くのが安全です。

セキュリティとSEO の考慮点

  • Open Redirect の防止:ユーザー入力をそのままリダイレクト先に使うとオープンリダイレクト脆弱性を招きます。外部URLを直接リダイレクトしない、ホワイトリストを使うなどの対策が必要です(OWASP 参照)。

  • SEO の最適化:恒久移転なら 301、一時的なら 302/307 を使う。チェーン状(A→B→C)のリダイレクトは検索エンジンに悪影響を与える場合があるため、できるだけ一段で新しい URL に戻すのがよいです。

  • HSTS:HTTPS を完全に強制したい場合はリダイレクトに加え、Strict-Transport-Security ヘッダの導入を検討します。これは .htaccess から設定可能ですが、慎重に扱ってください(サブドメインも強制される等)。

テストと検証方法

  • curl でヘッダ確認:curl -I -L https://example.com/ で Location ヘッダやステータスコードの遷移を確認します。

  • ブラウザの開発者ツール:Network タブでリダイレクトチェーンやレスポンスコードを確認できます。

  • サーバログ:アクセスログやエラーログで期待通りにリダイレクトされているかを追跡します。

まとめ

.htaccess によるリダイレクトは非常に有用で、サイトの移行、正規化、HTTPS 強制など幅広い用途で使われます。単純な置換には mod_alias(Redirect)が簡潔で、高度な条件分岐や正規表現が必要な場合は mod_rewrite(RewriteRule/RewriteCond)を使います。設計時にはステータスコードの選択、ルールの順序、クエリストリングの挙動、ループ回避、パフォーマンス、セキュリティ(オープンリダイレクト回避)などに注意してください。可能であればパフォーマンスと管理性の観点からサーバレベルの設定に移すことも検討しましょう。

参考文献