3秒でわかる
アクセスしてきたブラウザを別のURLへ自動で転送する動作。ページ移転後に古いリンクを生かしたり、フォーム送信後の二重送信を防いだりするのに使います。
もう少し詳しく
どういうものか
リダイレクトは、サーバーが「そのURLではなくこちらへ行ってください」と返し、ブラウザが自動で移動先を読み直す仕組みです。サーバーはステータスコード300番台と、移動先を示す Location ヘッダーを返します。ブラウザはアドレスバーのURLを書き換えて新しい場所を取得しに行くので、利用者から見ると最初から移動先を開いたように見えます。
なぜ必要か
URLは一度公開すると、ブックマークや他サイトのリンク、検索結果に残り続けます。ページを別の場所へ移したときに古いURLを404にすると、そこから来た人が全員行き止まりに突き当たります。リダイレクトを置けば、古いリンクを踏んだ人を新しいページへ運べます。恒久的な移動であることを301で伝えると、検索エンジンは評価を新しいURLへ引き継ぎます。
ログイン後に元の画面へ戻す、フォーム送信の完了後に結果ページへ移す、といった用途もあります。後者は二重送信を防ぐ意味があり、完了画面で再読み込みしても注文がもう一度作られません。
具体例
// Express での実装
app.get("/old-article", (req, res) => {
res.redirect(301, "/articles/new-slug"); // 恒久的な移動
});
app.post("/orders", async (req, res) => {
const order = await createOrder(req.body);
res.redirect(303, `/orders/${order.id}`); // 完了後はGETへ切り替える
});GET /old-article
→ 301 Moved Permanently
Location: /articles/new-slug
GET /articles/new-slug
→ 200 OKつまずきやすいところ
301は強力にキャッシュされます。ブラウザは一度受け取ると、次からサーバーに聞かずに移動先へ飛びます。設定を間違えた301を公開すると、直した後も利用者の手元では古い転送が生き続けます。移動先が確定していない段階では302を使い、確定してから301に変えるのが安全です。
もうひとつは転送のループです。httpをhttpsへ、www無しをwww有りへ、と別々に設定した結果、互いを指し合って ERR_TOO_MANY_REDIRECTS になる事故がよく起きます。転送の連鎖は1段で終わるようにまとめます。
POSTに対して301や302を返すと、ブラウザによってメソッドがGETに変わったり変わらなかったりします。挙動を確定させたいなら、GETに変えたいときは303、メソッドを保ったまま転送したいときは307を明示します。
似た用語との違い
| 方式 | 見た目のURL | 誰が判断するか |
|---|---|---|
| リダイレクト | 移動先に変わる | サーバーが指示しブラウザが移動 |
| リバースプロキシ | 変わらない | サーバー内部で転送先を差し替える |
| フォワード | 変わらない | アプリ内部で別の処理へ渡す |
URLが変わるかどうかが見分けの決め手です。