リダイレクト(転送)は、あるURLへのアクセスを、サーバーが別のURLへ送り直す仕組みです。301と302のどちらを返すかで検索結果に表示されるURLが変わり、307と308ではフォーム送信(POST)の扱いが変わります。この記事では、HTTPの仕様であるRFC 9110とGoogle検索セントラルの記述をもとに4つのコードの違いを整理します。あわせて.htaccess・Nginx・PHP・WordPress・HTMLでの書き方と、curlで設定を確かめる手順を解説します。Apache・PHPの設定例とPOST転送の挙動は、Apache 2.4.67・PHP 8.5.8・curl 8.7.1・Node.js v26.5.0で実際に動かして確認しました(NginxとWordPressは公式ドキュメントの記述によります)。
まとめ:301・302の選び方と設定・確認の要点
- 元に戻す予定のない移転には301を使います。フォームやAPIの送信先を移すなら308です。Googleは転送先のURLを検索結果に表示し、正規URLを決める強いシグナルとして扱います。
- 期間を区切った差し替えには302を使い、POSTを保つ必要があれば307を選びます。検索結果には転送元のURLが残りやすくなります。
- Googleは「301 やその他の永続的なリダイレクトによって PageRank の損失が生じることはありません」と明記しています。
- .htaccessの
RedirectとRewriteRuleの[R]、PHPのLocationヘッダー、WordPressのwp_redirect()は、コードを指定しないと302を返します。移転のつもりで書いた設定がこれに当たっていないか、最初に確かめてください。 - 設定後は
curl -Iでステータスコードと転送先を見ます。移転に使った転送は1年以上残します。
以下、仕組み、コードごとの違い、SEOへの影響、サーバー別の書き方、確認手順、転送を使わない方がよい場面の順に説明します。
リダイレクトの仕組み:3xxステータスコードとLocationヘッダー
ブラウザや検索エンジンのクローラーがURLを要求すると、サーバーは3桁のステータスコードを返します。300番台(3xx)は「別の場所を見てほしい」という意味の応答です。転送先のURLはLocationヘッダーで伝えます。受け取ったブラウザがLocationのURLを自動で要求し直すため、利用者にはアドレスバーのURLが切り替わったように見えます。
当社サイトのhttp://のURLを要求したときの応答が次のとおりです(2026年9月29日にcurl 8.7.1で取得)。
$ curl -I http://www.issoh.co.jp/
HTTP/1.1 301 Moved Permanently
Location: https://www.issoh.co.jp/
サーバーが返すのはステータスコードと転送先だけです。このサーバー側の転送のほかに、HTMLのmeta refreshやJavaScriptで、ページを読み込んだ後に移動させる方法もあります。こちらはクライアント側の転送と呼ばれ、Googleは使える場面を限っています(後述)。
301・302・307・308の違い:検索結果に出るURLとPOSTの扱い
| コード | RFC 9110での意味 | Googleの扱い | POSTの扱い | 主な用途 |
|---|---|---|---|---|
| 301 | 恒久的な移動 | 強いシグナル・転送先を表示 | GETに変わりうる | URL変更・ドメイン移転・HTTPS化 |
| 302 | 一時的に別のURI | 弱いシグナル・転送元を表示 | GETに変わりうる | メンテナンス・期間限定の差し替え |
| 303 | 別のリソースを参照 | 一時的な転送として扱う | GETで取り直す | フォーム送信後の結果ページ |
| 307 | 一時的に別のURI | 302と同じ | 変更してはならない | POSTを伴う一時転送 |
| 308 | 恒久的な移動 | 301と同じ | 変更してはならない | APIやフォーム送信先の移設 |
Googleは、307を302と、308を301と同じに扱うと明記しています。同時に、これらの「意味が大きく異なる」ことにも触れ、電子書籍リーダーや他の検索エンジンといった別のクライアントのために、適切なコードを使うよう求めています。SEOだけで見れば301と308に差はありません。差が出るのは、POSTを受けるURLです。
301リダイレクト:URLを戻さない移転で使う恒久転送
RFC 9110は301を、対象のリソースに新しい恒久的なURIが割り当てられ、今後の参照は新しいURIを使うべきという意味で定義しています。Googleは301を、転送先を処理すべきことを示す「強いシグナル」として扱い、検索結果には転送先のURLを表示します。ドメインの移転、HTTPS化、wwwの有無の統一、記事の統合で旧URLを残さない場合がこれに当たります。
302リダイレクト:検索結果に元のURLを残す一時転送
302は、対象のリソースが一時的に別のURIにあることを示します。Googleにとっては「弱いシグナル」で、検索結果には転送元のページが表示されやすくなります。Googleが例に挙げているのは、サービスが一時的に使えなくなったときに、状況を説明するページへ利用者を案内するケースです。メンテナンス画面や数日間だけのキャンペーンページ、ログイン後に元のページへ戻す処理も302の用途です。
302はエラーではありません。元のURLへ戻す予定がないのに302を使い続けると、検索結果に古いURLが残りやすくなります。
307・308:POSTを保つ転送とブラウザが内部で出す307
RFC 9110は307と308について、ユーザーエージェントはリクエストメソッドを変更してはならない(MUST NOT)と定めています。301と302には、歴史的にユーザーエージェントがPOSTをGETに変えてきたという注記が付いています。この曖昧さをなくすために用意されたのが307と308です。
Chromeの開発者ツールで自分のサイトに「307 Internal Redirect」と表示されても、サーバーの設定が原因とは限りません。Chromiumのソース(net/url_request/url_request_http_job.cc)では、HSTSが有効なホストへhttp://でアクセスすると、ブラウザが内部でhttps://への307を作ります。コメントには「Use status code 307 to preserve the method, so POST requests work.」とあります。この応答にはNon-Authoritative-Reason: HSTSが付き、サーバーは返していません。HSTSの仕組みと解除方法はHSTSが使用されているためアクセスできない原因と解除方法|HSTSの仕組み・設定・無効化までで解説しています。
POSTを送ったときの挙動:301・302・303ではフォームの中身が消える
RFCの注記が実際のクライアントでどう表れるかを、ローカルに立てたテスト用サーバーで確かめました(2026年9月29日、curl 8.7.1とNode.js v26.5.0のfetch)。サーバーは受け取ったメソッドと本文を返すだけで、a=1をPOSTし、各コードで/destへ転送させています。
| コード | curl -L -d | Node.js fetch | curl -X POST -L |
|---|---|---|---|
| 301 | GET・本文なし | GET・本文なし | POST・本文なし |
| 302 | GET・本文なし | GET・本文なし | POST・本文なし |
| 303 | GET・本文なし | GET・本文なし | POST・本文なし |
| 307 | POST・a=1 | POST・a=1 | POST・a=1 |
| 308 | POST・a=1 | POST・a=1 | POST・a=1 |
301・302・303では、ブラウザと同じ規則で動くfetchもcurlもGETに切り替えて送り直し、フォームの中身を捨てました。フォームの送信先やAPIのエンドポイントを301で移すと、移転先には空のGETが届きます。POSTを受けるURLの恒久移転には308、一時転送には307を使ってください。
curlの-X POSTにも落とし穴があります。転送後もメソッド名だけPOSTのまま送るため、成功しているように見えて本文は届いていません。curlのマニュアルが案内しているのは、POSTをGETに変えないための--post301・--post302・--post303で、転送の検証ではこちらを使います。
# 301なら移転先へGETで届く(ブラウザと同じ挙動)
curl -L -d 'a=1' https://example.com/form
# 301でもPOSTと本文を保ったまま転送をたどる
curl -L --post301 -d 'a=1' https://example.com/form
301と302のSEOへの影響:Google公式の記述
301とPageRank:永続的な転送で損失なしというGoogleの記述
Googleのサイト移転ガイドには「301 やその他の永続的なリダイレクトによって PageRank の損失が生じることはありません」とあります。「301で引き継げる評価は8〜9割」「転送を重ねると評価の一部が漏れる」という説明は、この記述と合いません。転送を何段も重ねるべきでない理由は評価の目減りではありません。Googlebotが追うのは最大10ホップまでで、段数が増えるほど利用者の待ち時間も延びるからです。ホップ数の上限と解消手順はリダイレクトチェーンとは?Googleは10ホップまで・推奨3個以下の根拠と解消手順で扱っています。被リンクの評価そのものの考え方はリンクジュースとは?仕組み・SEO効果と増やし方をわかりやすく解説が参考になります。
301と302を取り違えたときに起きること
違いは、検索結果に出るURLとして表れます。移転なのに302を返すと、Googleはこれを正規URLの弱いシグナルとしてしか扱わないため、転送元のURLが検索結果に残りやすくなり、新しいURLへの切り替わりが遅れます。逆に、メンテナンス中の一時転送に301を使うと、メンテナンス画面のURLが正規URLとして選ばれる可能性があります。
とはいえ、転送の種類は正規URLを決めるシグナルの1つにすぎません。Googleはcanonicalタグや内部リンクとあわせて判断します。取り違えに気づいたらコードを直し、転送先のページに旧URLへ向いたcanonicalが残っていないかも確認してください。canonicalの書き方はcanonicalタグとは?SEOでのURL正規化の目的・書き方・設定方法を解説にまとめています。
移転の転送を残す期間:一般的には1年以上
Googleの移転ガイドは「リダイレクトをできるだけ長く保持します(一般的には 1 年以上)」としています。その期間に、Googleが他サイトから旧URLへ張られたリンクを再クロールし、シグナルを新しいURLへ移すという説明です。同じガイドは、ユーザーの観点から無期限の保持を検討するよう勧めてもいます。外部サイトのリンクや利用者のブックマークは自社では書き換えられません。サーバーの引っ越しやCMSの入れ替えで転送ルールが消えないよう、ルールの一覧を移行手順に含めておきます。リニューアル全体の段取りはサイトリニューアルの進め方|SEO評価を落とさない6ステップと注意点で解説しています。
リダイレクトの設定方法:.htaccess・Nginx・PHP・WordPress・HTML
どの方法でも、最初に確かめるのは返るステータスコードです。次の表の書き方は、コードを指定しないと302になります。
| 環境 | 書き方 | 省略時 | 301にする指定 |
|---|---|---|---|
| Apache mod_alias | Redirect | 302 | Redirect permanent |
| Apache mod_rewrite | RewriteRule [R] |
302 | [R=301,L] |
| Nginx | return URL |
302 | return 301 URL |
| PHP | header('Location: …') |
302 | 第3引数に301 |
| WordPress | wp_redirect() |
302 | 第2引数に301 |
Apache・PHPの省略時の302は、Apache 2.4.67とPHP 8.5.8で実際に応答を取って確認しました。Nginxはnginx公式ドキュメントのreturnの説明、WordPressは関数リファレンスの既定値によります。
.htaccess(Apache):[R=301,L]の付け方とRedirectとの混在
RewriteEngine On
# ページ単位:旧URLを新URLへ1回で転送(ホスト統一のルールより前に置く)
RewriteRule ^old-page$ https://www.example.com/new-page [R=301,L]
# 条件付き:http とwww無しを https://www. へ1回で転送
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
HTTPS化とwww統一を別々のルールで書くと、http://example.comは2回転送されます。上の例のように1つの条件にまとめ、1回で最終URLへ送ります。CDNやロードバランサーでHTTPSを終端し、オリジンへはHTTPで接続する構成では、サーバーから見た%{HTTPS}が常にoffになり、転送がループします。
Apache 2.4.67で試すと、ドキュメントを読むだけでは気づきにくい挙動が2つありました。1つ目は[L]の付け忘れです。RewriteRule ^a$ /b [R=301]の後ろにRewriteRule ^(.*)$ /index.php [L]のような後続ルールがあると、応答は301なのにLocationヘッダーが付きませんでした。Apacheの公式ドキュメントも、[R]は「ほぼ常に」[L]と組み合わせるよう書いています。
2つ目は、.htaccessでRedirectとRewriteRuleを混在させたときの順序です。Apacheのドキュメント(When not to use mod_rewrite)は、.htaccessではmod_aliasが先に動くと説明しています。しかし2.4.67では、Redirect permanent "/old"より後ろに書いたRewriteRuleが先に適用されました。2.4.xのソースでも、ディレクトリ単位の処理(fixupsフック)にmod_rewriteがAPR_HOOK_FIRST、mod_aliasがAPR_HOOK_MIDDLEで登録されています。.htaccessではどちらか一方、実務ではRewriteRuleに統一するのが安全です。
Nginx:returnによる301の指定と省略時の302
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# ssl_certificate などは省略
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
# ssl_certificate などは省略
location = /old-page {
return 301 /new-page;
}
}
nginx公式ドキュメントでは、returnは301・302・303・307・308の各コードに転送先URLを指定でき、http://・https://・$schemeで始まるURLだけを書くと302になります。rewriteはpermanentフラグで301、redirectフラグで302です。1ページずつ移すなら、正規表現を使うrewriteよりlocation =(完全一致)とreturnの組み合わせの方が読みやすく、どのルールが効いたかも追いやすくなります。
PHP:header()のLocationは既定で302
<?php
header('Location: https://www.example.com/new-page', true, 301);
exit;
PHPマニュアルによると、Locationヘッダーは、201か3xxのステータスが設定済みでない限り302を返します。第3引数response_codeに301を渡すと301になり、PHP 8.5.8でも第3引数なしが302、ありが301でした。exitを書かないと後続の処理がそのまま動くため、転送の直後で止めます。
WordPress:wp_safe_redirect()とプラグイン「Redirection」
add_action( 'template_redirect', function () {
if ( is_page( 'old-page' ) ) {
wp_safe_redirect( home_url( '/new-page/' ), 301 );
exit;
}
} );
テーマのfunctions.phpに書く場合は、上のようにtemplate_redirectフックの中で対象ページを条件指定します。条件を付けずに書くと、すべてのリクエストが転送されます。wp_redirect()は第2引数$statusの既定値が302で、自動ではexitしません。リファレンスは直後にexit;を書くよう注記しています。転送先を自サイト内に限るなら、ホストを検証してから転送するwp_safe_redirect()を使います。コードを書かずに管理画面で転送を管理したい場合は、プラグイン「Redirection」(2026年9月時点で5.10.1、有効インストール200万以上)で301・302などを選んで登録できます。サーバーの移行作業の中で転送を扱うときはWordPress移行(サーバー引っ越し)の手順と注意点|自力と代行の判断基準も解説もあわせて確認してください。
HTMLだけで転送する:meta refreshとJavaScript
<meta http-equiv="refresh" content="0; url=https://www.example.com/new-page/">
サーバーの設定を変えられないレンタル環境や静的ホスティングでは、転送元のindex.htmlのheadにmeta refreshを書きます。Googleは、0秒のmeta refreshを永続的なリダイレクト、秒数を指定したmeta refreshを一時的なリダイレクトとして解釈します。JavaScriptのlocationによる転送は、「サーバー側のリダイレクトまたは meta refresh リダイレクトを行えない場合にのみ」使うよう書かれています。理由として挙がっているのは、レンダリングが失敗する場合があることです。
設定後の確認:curl・開発者ツール・Search Console
curlでのステータスコードと転送先の確認
# 1段目の応答だけを見る
curl -sI https://example.com/old-page
# 転送をたどり、各段のコードとLocationを並べる
curl -sIL https://example.com/old-page | grep -iE '^(HTTP|location)'
# 転送回数・最終のコード・最終URLだけを出す
curl -sL -o /dev/null -w '%{num_redirects} %{http_code} %{url_effective}\n' https://example.com/old-page
見るのは3点です。1段目が意図したコード(301か302か)になっているか。Locationが最終URLを直接指しているか。最終URLが200を返すか。転送が2回以上になっていたら、ルールを最終URLへの1回にまとめます。
ブラウザの開発者ツールで見るときの設定
Chromeの開発者ツールのネットワークタブは、「ログを保持」(Preserve log)をオンにしないと、ページ移動のたびに転送元の行が消えます。ステータス列に301や302、先に触れたHSTSの「307 Internal Redirect」が並ぶので、どれがサーバーの応答かを見分けます。ブラウザは一度受けた301をキャッシュすることがあります。設定を直した後の確認は、シークレットウィンドウかcurlで行います。
Search Consoleの「ページにリダイレクトがあります」
Search Consoleのページのインデックス登録レポートに出る「ページにリダイレクトがあります」は、別のページへ転送している非正規URLなので登録されない、という意味です。意図して301を設定した旧URLであれば対処は要りません。「リダイレクト エラー」は別の項目です。チェーンが長すぎる、ループしている、URLが最大長を超えた、チェーンに不正または空のURLがある、のいずれかで、こちらは修正が必要です。レポートの開き方はサーチコンソールとは?できること・設定手順とSEO改善への使い方【2026年時点】で紹介しています。
リダイレクトを使わない方がよい場面
- 削除して代わりのページがない:404か410を返します。Googleの移転ガイドは、多数の旧URLを関連の薄い1つのURL(新しいサイトのホームページなど)へまとめて転送すると、ユーザーが混乱し、soft 404とみなされる場合があるとしています。
- URLを残したまま重複を整理したい:並べ替えパラメータ付きのURLや印刷用ページのように、アクセスできる状態のまま正規URLを伝えたい場合は、転送ではなくcanonicalタグを使います。
- 言語や地域で自動的に振り分けたい:Googleは、利用者の言語を推測して別の言語版へ自動で転送することを避けるよう書いています。Googlebotは通常米国からクロールするため、すべての言語版が見つからない場合があるからです。言語の切り替えリンクを置きます(多言語サイトのURL設計は多言語サイト制作とは?進め方・費用相場と言語・URL設計の判断基準を解説)。
- 転送先を利用者の入力から決める:
?next=のような引数の値をそのまま転送先にすると、自社ドメインを踏み台にフィッシングサイトへ誘導されるオープンリダイレクトになります。転送先は自サイトのパスか、許可したホストの一覧に限ります。
転送は、同じ内容が別のURLへ移ったときに使う手段です。
よくある質問
「302エラー」と表示されるのはなぜですか?
302はエラーではなく、一時的な転送を示す正常な応答です。サイト診断ツールで302を指摘されたら、恒久的な移転なのに一時転送を返していないかを確かめます。移転であれば301に直し、メンテナンスやログイン後の遷移のように本当に一時的な転送であればそのままで構いません。転送が止まらずページが開かない場合は、302そのものではなく転送のループが原因です。
307はSEOに影響しますか?
Googleは307を302と同じに扱うと明記しているため、307だから不利になることはありません。検索結果には転送元のURLが残りやすくなります。開発者ツールに出る「307 Internal Redirect」は、HSTSや拡張機能によるブラウザ内部の転送で、サーバーの応答ではありません(応答ヘッダーのNon-Authoritative-Reasonに理由が出ます)。サーバーが実際に返すコードはcurlで確かめます。
301を設定した後で取り消せますか?
サーバーの設定を消せば、その時点から転送は止まります。ただしRFC 9110は301と308を、有効期限の明示がなくてもキャッシュが期限を推定して再利用してよい応答(heuristically cacheable)としています。そのため、一度アクセスした利用者のブラウザには古い転送が残ることがあります。後で取り消す可能性があるなら、最初から302を使うか、301の応答にCache-Control: max-ageで短い有効期限を付けておきます。
301リダイレクトを設定すると旧URLのインデックスはどうなりますか?
Googleが旧URLを再クロールして301を確認すると、検索結果には転送先のURLが表示されるようになります。旧URLはSearch Consoleで「ページにリダイレクトがあります」に分類され、インデックスには登録されません。切り替わる時期は再クロールの頻度で決まり、日付は保証されません。新しいURLをサイトマップに載せ、内部リンクを新URLへ書き換えておくと、Googleが新URLを見つけやすくなります。
Chromeの「ポップアップとリダイレクト」とは何ですか?
Chromeの設定の[プライバシーとセキュリティ]>[サイトの設定]>[ポップアップとリダイレクト]にある、サイトが新しいウィンドウを開いたり別ページへ移動させたりする動作を許可するかどうかの設定です。ブラウザ側で動作をブロックする機能で、サーバーが返す301や302とは関係がありません。特定のサイトだけ許可する場合は、ブロックされたページでアドレスバーのアイコンから「常に許可」を選びます。