SSL証明書・Go言語開発・Linuxサーバー構築・セキュリティ
執筆:株式会社エスロジカル(Webシステム受託開発・インフラ構築・運用改善)
URL 変更・サイト統合・HTTPS 化のたびに発生するのが「リダイレクト設計」です。
301 と 302 を取り違える、リダイレクトチェーンを伸ばす、ループを作ってしまう──いずれも
SEO 評価の取り損ねとリンク切れの遠因になります。
本記事では、実務で押さえておきたい設計原則と、Apache・Nginx での実装サンプルを整理します。
| コード | 名称 | 永続性 | メソッド変換 | 典型用途 |
|---|---|---|---|---|
| 301 | Moved Permanently | 永続 | 多くは GET に変換 | 恒久的な URL 変更・HTTPS 化(実務で最も頻用) |
| 302 | Found | 一時 | 多くは GET に変換 | キャンペーン期間中の差し替え・A/B |
| 303 | See Other | 一時 | GET に変換(明示) | POST 後 GET(PRG パターン) |
| 307 | Temporary Redirect | 一時 | 維持 | POST のまま別 URL へ転送 |
| 308 | Permanent Redirect | 永続 | 維持 | API の URL 恒久変更でメソッドを保ちたい |
選び方の原則:恒久的な変更なら 301(API では 308)。「いずれ元 URL に戻すかもしれない」ものだけ 302。 302 を使うと検索エンジンは新 URL に評価を集約しないため、サイト統合や HTTPS 化に 302 を使うのは典型的な失敗です。 ステータスコード全般の整理は HTTPステータスコード実務ガイド も参照してください。
?utm_source=... のような付加クエリは新 URL に引き継ぐ(広告計測が壊れる)。ERR_TOO_MANY_REDIRECTS で全停止。HTTPS 強制と www 強制を別々のルールで書くと起きやすい。4-1. mod_alias の Redirect(最もシンプル)
|
# 単一 URL の 301 リダイレクト Redirect 301 /old-page.html /new-page.html # 削除済みページに 410 Gone を返す(mod_rewrite 不要) Redirect 410 /retired-section/ |
4-2. mod_rewrite(パターンマッチが必要なとき)
|
RewriteEngine on # ファイル名の単純な 1対1 変換 RewriteRule ^old_page\.html$ /new-page.html [R=301,L] # http → https を強制(HSTS と組み合わせる) RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L] # 非 www を www に統一(同時に HTTPS 化) RewriteCond %{HTTP_HOST} ^example\.com$ RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L] |
注意:RewriteRule の [L] は「同じディレクトリ内のルール終端」を意味するだけで、サブディレクトリの .htaccess に処理が引き継がれることがある。
複雑な構成では [END](Apache 2.4 以降)を使うと完全終端できる。
5-1. return(最速・最も推奨)
|
# 単一 URL の 301 location = /old-page.html { return 301 /new-page.html; } # http を https に強制(別 server ブロックでまとめる) server { listen 80; server_name example.com www.example.com; return 301 https://www.example.com$request_uri; } # 非 www を www に統一(https 側) server { listen 443 ssl; server_name example.com; return 301 https://www.example.com$request_uri; } |
5-2. rewrite(パターンマッチが必要なとき)
|
# 旧 /blog/YYYY/MM/slug を /articles/slug に統一 rewrite ^/blog/\d+/\d+/(.+)$ /articles/$1 permanent; # permanent = 301 / redirect = 302 |
推奨:Nginx では rewrite より return のほうが正規表現評価が無く高速です。
Strict-Transport-Security ヘッダーを返してリダイレクト自体を削減(2回目以降のアクセスはブラウザ内部で https に書き換わる)。|
# 連鎖の全段表示(最大 10 段まで追跡) curl -ILs --max-redirs 10 https://example.com/old-page.html # 最終 URL とステータスだけ簡潔に確認 curl -o /dev/null -s -w "%{url_effective} %{http_code}\n" -L https://example.com/old-page.html |