【実務・中級編】HTTPステータスコード301 Moved Permanentlyと302 Foundの挙動差 – HTTPプロトコル・通信規格実践ガイド

リダイレクトの深淵:301と302を使い分ける「大人のエンジニア」の流儀

インフラエンジニアとして現場に立っていると、若手から「とりあえず動くから」という理由で、安易に302リダイレクトを乱発しているコードを見かけることがある。だが、君たちがブラウザの向こう側にいるユーザー体験(UX)や、検索エンジンのクローラーに与える影響を真剣に考えるのであれば、301と302の「魂の差」を理解しておく必要がある。

今回は、HTTPリダイレクトの基本にして最重要項目である、301と302の挙動を解剖していこう。

1. 301 Moved Permanently:恒久的な「転居届」

301は、サーバーからクライアントへ「このリソースはもうここにはない。これからはずっと新しいURLを使ってくれ」と伝えるメッセージだ。

RFCが定義する魂

RFC 7231に基づけば、301は「リソースの恒久的な移動」を指す。ここでのポイントは、ブラウザやキャッシュサーバーがこの結果をキャッシュし、次回から元のURLを叩かずに直接新しいURLへ向かう可能性があるという点だ。

  • SEOの影響: リンクジュース(検索エンジンの評価)が新しいURLへ適切に引き継がれる。
  • キャッシュの挙動: ブラウザが「もう前のURLは死んだ」と判断し、強制的に新URLを参照する。

実務での設定例 (Nginx)

恒久的な移動:古いドメインから新しいドメインへ転送する場合
server {
listen 80;
server_name old-site.com;

# permanentを指定するとステータスコード301が返る
return 301 https://new-site.com$request_uri;
}

2. 302 Found:あくまで「一時的な宿」

対して302は、「今はここにいないけれど、明日には戻ってくるかもしれない」という、一時的な避難先を指す。

なぜ302を使うのか

例えば、メンテナンス中や、サーバー側の都合で一時的に別のエンドポイントへ流したい場合がこれに当たる。重要なのは、ブラウザは302をキャッシュせず、毎回元のURLにリクエストを投げて確認し続けるという点だ。

  • SEOの影響: 検索エンジンは「一時的な移動」と判断し、元のURLの評価を維持する。
  • 注意点: 過去の歴史的背景から、多くのブラウザやクライアントライブラリが、302を受け取った際にメソッドを強制的にGETに変更する挙動(POSTで投げてもGETでリダイレクト先に飛ぶ)があるため、API設計では注意が必要だ。

Pythonによるリダイレクト確認コード

デバッグ時、実際にどう動いているかを確認するには、`requests`ライブラリを使うのが一番早い。

import requests

allow_redirects=Falseにしないと、ライブラリが勝手に追従してしまう
url = “http://example.com/temporary-page”
response = requests.get(url, allow_redirects=False)

print(f”ステータスコード: {response.status_code}”)
print(f”Locationヘッダー: {response.headers.get(‘Location’)}”)

結果:
301の場合はキャッシュの挙動が絡み、302の場合は毎回サーバーへ問い合わせが行われる

3. 現場で「死ぬほど困る」トラブルの正体

多くのエンジニアが陥る罠は、「とりあえず302にしておけば楽だ」という思考停止だ。

例えば、APIのバージョンアップでエンドポイントを変更した際、302を返すと、クライアント側が毎回無駄なラウンドトリップを繰り返すことになる。また、キャッシュサーバー(CDN)の設定次第では、301の結果がエッジサーバーにキャッシュされ、ロールバックが不可能になるという悪夢のような事態も起こり得る。

比較表:どっちを選ぶべきか?

| 特徴 | 301 (Moved Permanently) | 302 (Found) |
| :— | :— | :— |
| 用途 | URLの恒久変更 | メンテナンス・一時転送 |
| SEO評価 | 新URLに引き継がれる | 元URLが保持される |
| ブラウザの挙動 | キャッシュされる | 基本的にキャッシュされない |
| クライアント挙動 | 強力なリダイレクト | 一時的なリダイレクト |

4. 最後に:プロフェッショナルとしての判断基準

もし君がWeb APIの設計をしているのなら、基本は「301をデフォルト」と考えるべきだ。リソースの場所が変わるということは、クライアントのコードも更新されるべきだというメッセージだからだ。

逆に、302を選択するのは「どうしても今のリクエストを一時的に別の場所へ逃がさなければならない、かつ元のURLが正当であり続ける」という明確な理由がある時だけにしてほしい。

ネットワークは正直だ。プロトコルの意味を正しく理解し、適切なステータスコードを選択することは、単なる仕様の遵守ではない。ユーザーの端末で無駄な通信を発生させない、地球環境にも(微々たるものだが)優しい、筋の通ったエンジニアリングそのものなのだ。

次回のデバッグ時、`curl -I`を叩いたときに返ってくるステータスコードを見て、その裏にある設計者の意図を想像してみてほしい。きっと、以前より一段深い視点でネットワークが見えるはずだ。

コメント

タイトルとURLをコピーしました