307 Temporary Redirect とは?エラーではない理由と仕組みを解説
ブラウザーの開発者ツールを開いたら、ネットワークの一覧に「307」の文字が並んでいた。あるいは、プログラムのログに「307 Temporary Redirect」と出力されていた。そんな場面で「サーバーエラーが起きているのでは」と不安になった方は多いはずです。
結論から言うと、307 はエラーではありません。「このリソースは、いまは別の URL にあります。そちらへ同じ要求を送り直してください」というサーバーからの案内です。HTTP のステータスコードは番号の先頭の数字で大まかな性格が分かれていて、3 で始まるものはリダイレクト(転送)を表します。エラーを表すのは 4 で始まるもの(クライアント側の問題)と、5 で始まるもの(サーバー側の問題)です。
分類
3xx のリダイレクト。エラーではなく、転送の案内です。
意味
いまは別の URL にあります。元の URL は今後も使い続けてください。
最大の特徴
要求メソッドと本文を変えずに、移動先へ送り直させます。
定義
RFC 9110 の 15.4.8 に定められています(確認日: 2026年10月9日)。
「エラー」と呼ばれがちな 307 が、本当に困る場面
307 そのものは正常な応答ですが、実際の現場では「307 のせいで困った」という相談が絶えません。困りごとは、おおむね次の 3 つに分かれます。
1 つ目は、リダイレクトが終わらない問題です。移動先からさらに別の場所へ、そして元の場所へと転送が続くと、ブラウザーは途中で通信をあきらめ、「リダイレクトが多すぎます」といったエラー画面を表示します。このとき画面に出るのはエラーですが、原因は 307 という応答そのものではなく、転送の設定の組み合わせにあります。
2 つ目は、API やスクリプトからの通信で、転送先に要求が届かない問題です。HTTP クライアントの中には、リダイレクトを自動では追いかけない設定のものがあります。その場合、307 が返ってきた時点で処理が止まり、呼び出し側からは「失敗した」ように見えます。
3 つ目は、開発者ツールに 307 が大量に並び、サーバーが不具合を起こしているように見える問題です。これはブラウザーが自分で作り出した転送の記録であることが多く、後述するように、実際にはサーバーへ要求が出ていない場合もあります。
つまり、困りごとの大半は「307 を誤解していた」か「転送の設定が噛み合っていなかった」のどちらかです。仕組みを正しく押さえておけば、慌てる必要はありません。
307 が伝えていること
HTTP の標準仕様である RFC 9110 は、307 を次のように位置づけています。対象のリソースは一時的に別の URI にあり、ユーザーエージェント(ブラウザーなどのクライアント)が自動でリダイレクトを行う場合は、要求メソッドを変更してはならない。転送は時間とともに変わりうるので、クライアントは今後も元の URI を使い続けるべき、という内容です。
ここには 2 つの重要な約束事があります。
約束その 1: メソッドを変えない
たとえば、フォームの内容を POST で送信したとします。サーバーが 307 で別の URL を案内したら、クライアントは移動先にも POST で、同じ本文を送り直します。GET に切り替えたり、本文を捨てたりしてはいけません。
約束その 2: 元の URL は今後も有効
307 は「一時的な」移動です。クライアントは、次回以降も最初の URL にアクセスします。移動先の URL を覚えて、次からそちらへ直接行く、という動きは想定されていません。恒久的に移ったことを伝えたいときは、301 や 308 の役割になります。
サーバーが添える Location ヘッダー
307 の応答には、移動先を示す Location ヘッダーを付けるのが基本です。RFC 9110 でも、サーバーは Location を含めるべきとされています。クライアントは、その値を元の要求の URL に対して解決した結果へ移動します。つまり、Location には絶対 URL だけでなく、相対的な指定も書けます。
実際のやり取りは、次のようになります。
clientserver
最初の応答が 307 でも、最終的な結果は 201 のような成功のステータスになります。この流れを知っていれば、ログに 307 が見えること自体は、まったく心配いりません。
307 が生まれた歴史的な理由
307 という番号がなぜ必要になったのかは、歴史を知ると腑に落ちます。
初期の HTTP では、一時的な移動を表す 302 は「メソッドを変えてはならない」前提で作られていました。ところが現実には、多くのブラウザーが 302 を受け取ると、POST を GET に切り替えて移動先へ向かう実装になっていきました。1999 年 6 月に公開された RFC 2616(HTTP/1.1)には、この状況がそのまま書かれています。以前の仕様では 302 でメソッドを変えることを禁じていたが、既存のユーザーエージェントの多くは 302 を 303 のように扱っている、という趣旨の注記です。
実装が先に進んでしまった以上、302 の意味を後から固定することはできません。そこで RFC 2616 は、サーバーが期待する動作を曖昧にさせないために、303 と 307 を追加しました。「GET で取得し直してほしい」場合は 303、「メソッドを保ったまま送り直してほしい」場合は 307、という役割分担です。
その後の RFC 9110(2022 年に公開された、現在の HTTP の意味論の仕様)も、301 と 302 では POST から GET への変更を認めたうえで、メソッドを保ちたいなら 307 や 308 を使うよう案内しています。つまり 307 は、長年の実装の揺れを整理するために生まれた、意図をはっきり伝えるための番号なのです。
3xx の仲間のなかでの位置づけ
リダイレクトを表すステータスコードは、一つではありません。主なものを並べると、307 の立ち位置が分かりやすくなります。
| コード | 名称 | 恒久/一時 | 自動転送でのメソッド |
|---|---|---|---|
| 301 | Moved Permanently | 恒久 | POST が GET に変わることがある |
| 302 | Found | 一時 | POST が GET に変わることがある |
| 303 | See Other | 一時 | GET(または HEAD)で取得し直す |
| 307 | Temporary Redirect | 一時 | 変えない |
| 308 | Permanent Redirect | 恒久 | 変えない |
RFC 9110 は、301 と 302 について、ユーザーエージェントが POST を GET に変えてもよい(MAY)と書いています。これは、仕様が整う前に実装が先行した歴史的な経緯によるものです。メソッドを確実に保ちたい場合の選択肢として、一時的な転送には 307、恒久的な転送には 308 が用意されました。
違いをさらに詳しく知りたい場合は、301・302・303・307・308 の違いと、307 と 302 の違いも合わせてご覧ください。
一時的な移動を、正しく伝えられる強み
ここからは、307 を理解しておくことで得られる利点です。
利点 1: 書き込み系の通信を安全に転送できる
GET だけのページであれば、301 でも 302 でも大きな差は出ません。しかし、フォーム送信や API の更新処理のように、POST・PUT・DELETE を使う通信では話が変わります。メソッドが勝手に GET へ変わると、更新が実行されないまま「成功したように見える」事態も起こりえます。307 を使えば、仕様上、メソッドと本文が維持されるため、転送の前後で処理の意味が変わりません。
利点 2: 「いつか元に戻す」移動に向いている
メンテナンス中だけ別のサーバーへ振り向ける、一時的に負荷分散先を切り替える、障害時に代替の場所へ案内する、といった用途です。307 は「元の URL を今後も使ってほしい」という意思表示そのものなので、あとで元に戻したときに、クライアント側に古い転送先が残りにくい設計になっています。
利点 3: キャッシュの扱いが明確
RFC 9110 は、300・301・308 を、明示的な指定がなくても保存してよい(ヒューリスティックにキャッシュ可能な)応答として扱っています。302 や 307 は、そこに含まれていません。サーバーが Cache-Control や Expires で保存期間を明示した場合にだけ、キャッシュの対象になります。何も指定しなければ、一時的な転送がいつまでも残る心配は小さくなります。
利点 4: 検索エンジンにも「一時」と伝わる
Google 検索セントラルの文書では、307 は 302 と同等に扱われ、リダイレクト先を正規 URL とする弱いシグナルとして処理されます。一時的な移動を伝える目的に合っています。詳しくは検索エンジンとの関係で解説します。
ブラウザーが作る「307 Internal Redirect」も知っておく
開発者ツールで、サーバーに要求を出していないのに 307 が表示されることがあります。これは、ブラウザーが HSTS(HTTP Strict Transport Security)の設定にしたがって、http の URL を https に自分で書き換えた記録です。Chromium のソースコードでは、このとき状態コードに 307 を使う理由を「メソッドを保つことで、POST 要求が正しく動くようにするため」と説明しています。
この場合の 307 は、サーバーが返したものではありません。サーバー側の設定を直す必要はなく、むしろ HSTS が正しく働いている証拠です。詳しくは307 Internal Redirect と HSTSで説明しています。
307 を見かけたときの確認ポイント
実務で 307 に出会ったら、次の順に確認すると、原因の切り分けが進みます。
- 移動先(Location)を確認する。 意図した URL に向いているか、同じ場所へ戻っていないかを見ます。
- 転送の回数を確認する。 1 回で最終ページに着くなら正常です。何度も続くなら、設定の組み合わせを疑います。
- 要求メソッドを確認する。 POST が移動先でも POST のままなら、307 の約束どおりに動いています。
- サーバーが返したものか、ブラウザーが作ったものかを見分ける。 後者なら、サーバー側の対処は不要です。
コマンドラインなら、curl -i で応答ヘッダーを確認できます。リダイレクトを追いかけながら最終地点まで見るなら curl -iL です。curl は -L を付けると転送を自動で追いますが、POST は 301・302・303 では GET に変わり、それ以外の 3xx(307 や 308 を含む)では元のメソッドが保たれます。
手元で 307 の応答を確かめる
自分のサイトが返している応答を確かめるなら、次のようにヘッダーだけを取得するのが手軽です。-I を使うと HEAD 要求になるため、POST の動きを確かめたいときは -i と -X POST を組み合わせます。
# 応答ヘッダーを表示(転送は追わない)
curl -i https://example.com/old
# 転送を追いかけ、最終的な URL と転送回数だけを表示
curl -sL -o /dev/null -w '%{url_effective} %{num_redirects}\n' https://example.com/old
1 つ目のコマンドでは、HTTP/2 307 と location: の行が見えれば、サーバーが 307 を返しています。2 つ目のコマンドは、最終地点と転送回数を一行で確認できます。回数が想定より多いときは、転送の途中に余計な設定が挟まっているサインです。
307 は「正しく使えば頼れる案内役」
ここまでの要点を整理します。
- 307 はエラーではなく、「いまは別の URL にあります」という一時的な転送の案内です。
- 最大の特徴は、メソッドと本文を変えずに移動先へ送り直させる点です。
- 恒久的な移動には 301 か 308、POST の後に結果画面へ移すには 303 と、役割に応じて使い分けます。
- 開発者ツールに表示される「307 Internal Redirect」は、多くの場合ブラウザーによる HSTS の処理で、サーバーの不具合ではありません。
困ったときに疑うべきは 307 という番号そのものではなく、転送の行き先や回数、そして組み合わせです。次は、301・302・303・307・308 の違いを押さえておくと、リダイレクトの設計と原因調査の両方が、ぐっと楽になります。サーバーで 307 を返したい場合は、nginx、Apache、PHP それぞれの設定例が役立ちます。