HTTP 302 Foundを徹底解説:動作原理・実装・SEO・セキュリティまで

概要:302 Foundとは何か

302 Found(旧称:Moved Temporarily)は、HTTPレスポンスステータスコードの一つで、クライアントが要求したリソースが一時的に別の場所にあることを示します。サーバーはレスポンスヘッダの Location フィールドにリダイレクト先のURIを返し、クライアント(通常はブラウザ)はそのURIに再度アクセスします。302は「一時的な移動」を意図しており、恒久的な変更を示す301 Moved Permanentlyとは意味合いが異なります。

歴史と仕様(RFCの変遷)

HTTPの仕様は何度か更新され、302の扱いも変わってきました。RFC 2616(HTTP/1.1、1999年)では302のユーザーエージェントの振る舞いが曖昧で、POSTが302で返されたときにGETへ変換する実装が多く見られました。これを明確化するため、RFC 7231(2014年)では302は「一時的リダイレクト」として定義されつつも、歴史的な振る舞い(多くのUAがメソッドをGETに変えている)を認める説明が付けられました。

また、POSTなどのメソッドの扱いを保存したい場合は307 Temporary Redirect、恒久的に保存したい場合は308 Permanent Redirect(RFC 7538)を使うべきである、という指針が確立されています。

クライアントの振る舞い(ブラウザ、curl等)

  • Location ヘッダを受け取ったクライアントは基本的にリダイレクト先へアクセスする。
  • 歴史的経緯により、多くのブラウザはPOSTに対する302レスポンスを受け取ると、リダイレクト先へGETで再リクエストする(結果としてPOSTボディは破棄される)。
  • 302は「一時的」であるため、ブラウザ側は通常リダイレクトをキャッシュしない。ただし、レスポンスに明示的なキャッシュ制御ヘッダがついていればその指示に従う。

302と他のリダイレクトコードの違い

  • 301 Moved Permanently:恒久的移転。検索エンジンは基本的に元のURLのインデックスを新しいURLへ移行する。
  • 302 Found:一時的移転。検索エンジンは基本的に元のURLを維持し、将来的には元に戻る可能性があると判断する。
  • 303 See Other:常にGETに変換してリダイレクトすべき場合(主にPOST後のPRGパターン)に使用。
  • 307 Temporary Redirect:302の「方法を変更しない」バリアント。元のHTTPメソッドを保持してリダイレクトすることを明示。
  • 308 Permanent Redirect:307の恒久版。メソッドを保持して恒久的に移動することを示す。

実装例(サーバーサイド/サーバ設定)

典型的なレスポンス例(ヘッダのみ):

<HTTP/1.1 302 Found>
<Location: https://example.com/new-path>
<Content-Length: 0>

Apache (.htaccess / httpd.conf) の例:

RewriteEngine On
RewriteRule ^old-path$ /new-path [R=302,L]

または簡単に:

Redirect 302 /old-path https://example.com/new-path

Nginx の例:

location = /old-path {
return 302 https://example.com/new-path;
}

言語別の例(PHP):

header('Location: /new-path', true, 302);
exit;

Node/Express の例:

res.redirect(302, '/new-path'); // Express は引数なしなら 302 をデフォルトにする

キャッシュとCache-Controlの扱い

302自体は「一時的」なリダイレクトを示すため、デフォルトではクライアントやプロキシが恒久的にキャッシュすることは想定されていません。ただし、RFCの仕様上はレスポンスにCache-Control や Expires といった明示的なキャッシュヘッダが付与されていれば、その指示に従ってキャッシュできます。したがって、短期間だけのリダイレクトであっても、意図しないキャッシュを防ぐために Cache-Control: no-store や no-cache を付与するのが安全です。

SEO(検索エンジン最適化)への影響

検索エンジンは302を「一時的な移転」と解釈します。つまり、元のURLの評価(ランキングやインデックス)は通常維持されます。恒久的にURLを変更したい場合は301を使うべきです。ただし、実務では検索エンジンが長期間にわたり302を検出すると、状況に応じて301相当として扱うことがあるため、意図しないインデックス変化を避けるために適切なステータスを使い分けることが重要です。

主なポイント:

  • 一時的にページを差し替えるときは302が適切。
  • 恒久的に移転したら301を使い、内部リンクやcanonicalも更新する。
  • POST後のリダイレクトはPRGパターンで303を検討するとユーザー体験が安定する。

セキュリティと脆弱性

リダイレクトに関連する代表的な脆弱性は「オープンリダイレクト」です。外部からの入力をそのままLocationに入れると、攻撃者が悪意のあるサイトへユーザーを誘導できます。対策としては、リダイレクト先をホワイトリストで検証する、あるいは内部パスのみ許可するなどが必要です。

その他の注意点:

  • Locationにユーザー入力を埋め込む際は検証・正規化を行う。
  • クロスオリジンの取り扱いに注意(CORSやセキュリティヘッダ)。
  • HTTPS と HTTP の混在リダイレクトは中間者攻撃のリスクを招くことがあるため、可能な限り HTTPS へ統一する。

トラブルシューティングとデバッグ

リダイレクトの問題を調査する際に有用な手法:

  • curl -I -L を使ってヘッダチェーンを確認する(-I はヘッダのみ、-L はリダイレクト追従)。例: curl -I -L https://example.com/old-path
  • ブラウザの開発者ツールの Network タブでステータスと Location ヘッダ、転送回数を確認する。
  • プロキシやCDNが介在している場合は、CDNの設定でリダイレクトルールやキャッシュヘッダが付いていないかを確認する。
  • 無限リダイレクト(ループ)や予期しないメソッド変換(POST→GET)が起きていないかをチェックする。

ベストプラクティスまとめ

  • 「一時的」な置き換えには302、恒久的な移動には301を使い分ける。
  • POSTをリダイレクトする場合は、意図したHTTPメソッドが維持されるか(307/308)またはGETに変換するか(303)を明確にする。
  • Location は可能なら絶対URLを使う(互換性確保)。ただしRFC 7231では相対参照も許容される。
  • Cache-Control ヘッダでキャッシュ方針を明示する。意図しないキャッシュを避けたい場合は no-store / no-cache を付与。
  • 外部入力をリダイレクト先に使う場合はホワイトリストで検証し、オープンリダイレクトを防ぐ。

実務でよくあるケース

  • メンテナンスページへの一時遷移:302 を使い、ユーザーを一時的にメンテナンスページへ誘導。
  • A/B テストや機能フラグでの切替:短期間の差し替えは302で運用し、結果を確認して恒久変更なら301へ切替。
  • フォーム送信後のPRG(Post/Redirect/Get):POST後に結果ページへ戻す際は303を採用すると確実。

まとめ

302 Foundは「一時的なURL移転」を示す重要なステータスコードであり、正しく使うことでユーザー体験やシステムの整合性を保てます。一方で、歴史的なブラウザやクローラの挙動を踏まえて、307/303/308などのより明確なコードを用途に応じて使い分けること、キャッシュ制御やセキュリティ対策(オープンリダイレクト防止)を併せて実施することが重要です。

参考文献