この記事の要点
• HTTPリダイレクトは301/308が恒久、302/307が一時の転送を表す
• 301と302はPOSTをGETに変更、307と308はメソッドを維持する
• SEOでは301/308がリンク評価を引き継ぐため、永久的なURL変更に必須
HTTPリダイレクトとは
HTTPリダイレクトは、クライアント(ブラウザ)が要求したURLとは異なるURLへ自動的に転送する仕組みです。サーバーは3xxステータスコードとLocationヘッダーで新しいURLを返します。
なぜ必要か: ページの移転、HTTPからHTTPSへの誘導、正規URLの統一(www有無の統一など)、メンテナンス時の一時移転など、様々な場面で使われます。
リダイレクトの基本動作
# curlでリダイレクトを確認(-Iでヘッダーのみ取得)
curl -I http://example.com/old-page
# レスポンス例
HTTP/1.1 301 Moved Permanently
Location: http://example.com/new-page
- クライアントがリクエスト送信
- サーバーが
3xxステータスコードとLocationヘッダーを返す - クライアントが
LocationのURLへ自動的に再リクエスト - 新しいURLのレスポンスを取得
4つのリダイレクトステータスコード
主要なリダイレクトコードの比較
| コード | 種類 | メソッド変更 | キャッシュ | 主な用途 |
|---|---|---|---|---|
| 301 | 恒久 | POST→GET | あり | URL変更、ドメイン移転 |
| 302 | 一時 | POST→GET | なし | 一時的なメンテナンス |
| 307 | 一時 | 維持 | なし | フォーム再送信(一時) |
| 308 | 恒久 | 維持 | あり | HTTPS強制(POST維持) |
ポイント: 301と302はPOSTリクエストをGETに変更するため、フォーム送信の転送では使えません。メソッドを維持したい場合は307か308を使用します。
301 Moved Permanently
恒久的な移転を表します。リソースが永久に新しいURLへ移動したことを示します。
特徴
- キャッシュ: ブラウザが積極的にキャッシュ(明示的なキャッシュ制御がなくても)
- メソッド変更: POSTリクエストはGETに変更される
- SEO影響: 旧URLの評価が新URLに引き継がれる
使用例
# ドメイン移転
http://old-domain.com/ → http://new-domain.com/ (301)
# URL構造変更
http://example.com/blog/2025/01/post → http://example.com/articles/post (301)
# wwwの統一
http://example.com → http://www.example.com (301)
注意: 301は強力にキャッシュされるため、誤ったリダイレクトを設定すると修正が困難になります。本番環境では慎重に設定してください。
302 Found
一時的な移転を表します。リソースが一時的に別のURLにあることを示します。
特徴
- キャッシュ: デフォルトではキャッシュされない
- メソッド変更: POSTリクエストはGETに変更される
- SEO影響: 旧URLの評価は維持される(新URLには移らない)
使用例
# メンテナンス中
http://example.com/ → http://example.com/maintenance (302)
# 言語選択(初回のみ)
http://example.com/ → http://example.com/ja/ (302)
# A/Bテスト
http://example.com/product → http://example.com/product-variant-a (302)
実務のヒント: SEOで旧URLの評価を保ちたい一時的な移転では302を使います。ただし、数週間以上続く場合は301を検討しましょう。
307 Temporary Redirect
**一時的な移転(メソッド維持)**を表します。302の改良版です。
特徴
- キャッシュ: デフォルトではキャッシュされない
- メソッド維持: POSTリクエストはPOSTのまま転送される
- SEO影響: 旧URLの評価は維持される
使用例
# フォーム送信先の一時変更
POST http://example.com/api/v1/submit → POST http://example.com/api/v2/submit (307)
# ログイン後のリダイレクト(POSTデータ維持)
POST http://example.com/login → POST http://example.com/dashboard (307)
302との違い
| 項目 | 302 Found | 307 Temporary Redirect |
|---|---|---|
| メソッド | POST→GET | POSTのまま |
| 標準準拠 | 曖昧な仕様 | 明確な仕様(HTTP/1.1) |
| 使用場面 | GETリクエストの一時転送 | POSTリクエストの一時転送 |
実践メモ: フォーム送信のリダイレクトでは、データ損失を防ぐために307を使用しましょう。
308 Permanent Redirect
**恒久的な移転(メソッド維持)**を表します。301の改良版です。
特徴
- キャッシュ: ブラウザが積極的にキャッシュ
- メソッド維持: POSTリクエストはPOSTのまま転送される
- SEO影響: 旧URLの評価が新URLに引き継がれる
使用例
# HTTP→HTTPS強制(APIエンドポイント)
POST http://api.example.com/data → POST https://api.example.com/data (308)
# APIバージョン移行(メソッド維持)
POST http://example.com/api/v1/users → POST http://example.com/api/v2/users (308)
301との違い
| 項目 | 301 Moved Permanently | 308 Permanent Redirect |
|---|---|---|
| メソッド | POST→GET | POSTのまま |
| 標準準拠 | HTTP/1.0(古い) | HTTP/1.1(新しい) |
| 使用場面 | GETリクエストの永久転送 | POSTリクエストの永久転送 |
SEOへの影響
リダイレクトコードの選択は検索エンジン最適化に大きく影響します。
SEO観点での比較
| コード | リンク評価 | インデックス | 推奨場面 |
|---|---|---|---|
| 301 | 新URLに移転 | 旧URL削除→新URL登録 | 永久的なURL変更 |
| 302 | 旧URLのまま | 旧URLを維持 | 一時的な変更 |
| 307 | 旧URLのまま | 旧URLを維持 | 一時的な変更(POST) |
| 308 | 新URLに移転 | 旧URL削除→新URL登録 | 永久的な変更(POST) |
SEOのベストプラクティス: URL変更が永久的なら301/308、一時的(数週間以内に元に戻る)なら302/307を選択します。
Locationヘッダーの記述
リダイレクト時に必須のLocationヘッダーの記述例です。
# Nginxの設定例
location /old-page {
return 301 https://example.com/new-page;
}
# Apache .htaccessの例
Redirect 301 /old-page https://example.com/new-page
# Node.js/Expressの例
app.get('/old-page', (req, res) => {
res.redirect(301, '/new-page');
});
リダイレクトループの注意
誤った設定でリダイレクトが無限に続く状態です。
よくある原因
# 危険な例: A→B→A のループ
http://example.com/a → http://example.com/b (301)
http://example.com/b → http://example.com/a (301)
# 危険な例: HTTPS強制とwww統一の衝突
http://example.com → https://www.example.com (301)
https://www.example.com → http://example.com (301)
防止策
- リダイレクトチェーンは3段階以内に抑える
- 設定前にテスト環境で確認する
curl -Lで最終的な到達先を確認する
# リダイレクトチェーンを追跡
curl -L -I http://example.com/old-page
リダイレクトの実装パターン
HTTP→HTTPS強制
# Nginx
server {
listen 80;
server_name example.com;
return 308 https://$server_name$request_uri;
}
www統一
# Apache
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
言語別リダイレクト
// JavaScript
const userLang = navigator.language.startsWith('ja') ? 'ja' : 'en';
if (window.location.pathname === '/') {
window.location.replace(`/${userLang}/`); // 302相当
}
ポイント: クライアント側(JavaScript)でのリダイレクトはSEOに悪影響を与える可能性があります。可能な限りサーバー側で実装しましょう。
その他のリダイレクトコード
| コード | 名称 | 用途 |
|---|---|---|
| 303 | See Other | POSTの後にGETへリダイレクト(PRGパターン) |
| 304 | Not Modified | キャッシュが有効(リダイレクトではない) |
| 305 | Use Proxy | プロキシ経由での接続(廃止予定) |
303 See Other: POST-Redirect-GET(PRG)パターンで使われます。フォーム送信後にブラウザの「再読み込み」で二重送信を防ぐために使用します。
トラブルシューティング
# リダイレクトステータスを確認
curl -I http://example.com/test
# リダイレクトチェーンを追跡
curl -L -I -s http://example.com/test | grep -E "HTTP|Location"
# ブラウザキャッシュをクリア(開発者ツール)
# Chrome: DevTools → Network → Disable cache にチェック
まとめ
HTTPリダイレクトは4つの主要コードを使い分けます。恒久的なURL変更には301/308、一時的な変更には302/307を使用します。また、POSTリクエストを維持したい場合は307/308を選択することが重要です。SEOでは恒久的リダイレクト(301/308)のみがリンク評価を引き継ぐため、慎重に選択しましょう。
注意: 301と308は強力にキャッシュされます。本番環境で誤ったリダイレクトを設定すると修正が困難になるため、必ずテスト環境で検証してください。
参考リソース
- RFC 9110 - HTTP Semantics (Section 15.4 Redirection)
- MDN - HTTP redirections
- Google Search Central - 301 vs. 302 redirects
- Cloudflare Learning - What is an HTTP redirect?