クリックしたリンクと、実際に表示されるページが同じとは限りません。その間には、HTTPS へのアップグレード、ホストの変更、トラッキングサービス、URL 短縮サービス、末尾にスラッシュを付ける CMS のルールなどが挟まっていることがあります。そのひとつひとつが、ブラウザーが知らせることなく送っている個別のリクエストです。
このガイドでは、TrueURL、curl、ブラウザーのデベロッパーツール(DevTools)でこうしたステップを確認する方法、リダイレクトチェーンの各部分の意味、そしてよくある問題の直し方を解説します。
リダイレクトチェーンとは
リダイレクトは、サーバーが 3xx の HTTP ステータスコードと、別の URL を示す Location ヘッダーを返したときに発生します。ブラウザーやクローラーなどのクライアントはその URL にリクエストを送り、リダイレクトではないレスポンスが返ってくるまでこれを繰り返します。
1 回のリクエストとそのレスポンスを、1 つのホップと呼びます。最初の URL から最終的なレスポンスまでの一連の流れ全体が、リダイレクトチェーンです。
# URL Status Location
1 http://example.com/Shoes 301 https://example.com/Shoes
2 https://example.com/Shoes 301 https://www.example.com/Shoes
3 https://www.example.com/Shoes 302 /shoes/
4 https://www.example.com/shoes/ 2001 つのページにたどり着くまでに、リダイレクトが 3 回、リクエストが 4 回発生しています。3 ホップ目の Location は相対パスです。RFC 9110 の規定どおり、クライアントは直前にリクエストした URL を基準にこれを解決するため、https://www.example.com/shoes/ を意味します。理想的には、これらのアドレスはどれも 1 ホップで最終 URL に到達するべきです。
ページが 200 OK を返した後に、<meta http-equiv="refresh"> タグや JavaScript でリダイレクトすることもあります。こうしたクライアントサイドリダイレクトもチェーンの一部ですが、curl のように HTTP ヘッダーしか読まないツールは、そのページで止まってしまいます。
リダイレクトを確認すべき理由
SEO:正規 URL のシグナルとクロールバジェット
検索エンジンは、リダイレクトを「どの URL をインデックスに登録すべきか」を示すものとして読み取ります。Google は、恒久的なリダイレクト(301 と 308)を、リダイレクト先を正規 URL とすべきだという強いシグナルとして扱います。一時的なリダイレクト(302、303、307)は弱いシグナルです。そのため、恒久的に移転したページを 302 でリダイレクトしていると、検索結果に古い URL が残り続けることがあります。
チェーンの長さも重要です。Googlebot はリダイレクトを最大 10 ホップまでたどり、それまでにコンテンツを取得できなければ、Search Console でリダイレクトエラーとして報告されます。Google のクロールバジェットに関するガイドでも、長いリダイレクトチェーンはクロールに悪影響を及ぼすとして、避けるよう勧めています。
ページの表示速度
最後のリダイレクトへの応答が返ってくるまで、最終ページは読み込みを始められません。ホップごとにネットワークの往復が 1 回発生し、別のホストへのホップでは、さらに DNS ルックアップ、新しい接続、HTTPS の場合は TLS ハンドシェイクも必要になります。モバイル回線では、3〜4 回のリダイレクトによって、実際のページの最初の 1 バイトが届くまでに数百ミリ秒が上乗せされることもあります。各ホップにかかる時間は、リダイレクト速度チェッカーで確認できます。
短縮リンクや見慣れないリンクの安全性
短縮リンクや、メールに含まれる多くのトラッキングリンクは、リンク先を隠しています。フィッシング詐欺では有名なドメインのオープンリダイレクトが悪用されることもあり、信頼できるサイトから始まるリンクが、まったく別の場所にたどり着くことがあります。短縮 URL 展開ツールを使えば、クリックする前に、途中で経由するすべてのドメインと、HTTPS から暗号化されていない HTTP に切り替わるホップがないかを確認できます。
アフィリエイトリンクとトラッキングリンク
マーケティング用のリンクは、ランディングページに着くまでに複数のサービスを経由することがよくあります。それぞれのサービスがクエリ文字列を引き継がなければ、UTM パラメーター、クリック ID、アフィリエイトタグは気づかないうちに失われてしまいます。最終 URL を見れば、それらが残っているか、リンクが今も意図したページに到達しているかがわかります。
サイト移転、HTTPS 化、正規ホスト
サイトリニューアル、ドメイン移転、HTTPS 化の後は、すべての古い URL が、1 回の恒久的なリダイレクトで対応する新しい URL に到達する必要があります。サイトの基本的な 4 つのバリエーション(http:// と https://、それぞれ www ありとなし)は、すべて 1 つの正規アドレスにたどり着かなければなりません。こうしたルールは気づかないうちに壊れます。新しい CDN ルール、プラグインの更新、サーバーの移転によって、誰にも気づかれないままホップやループが増えることがあるのです。
TrueURL でリダイレクトを確認する方法
TrueURL はすべてのチェックを Cloudflare のエッジネットワーク上で実行するため、信頼できないリンクも、自分のブラウザーで開かずに調べられます。トップページの URL リダイレクトチェッカーでは 1 つの URL をチェックでき、リダイレクトチェーンチェッカーなどの専用ツールも同じエンジンを使っています。
ステップ 1:URL を入力する
URL を貼り付けて、チェックを実行します。スキームを省略した場合は https:// とみなされます。暗号化されていない HTTP をテストするには、http:// から入力してください。
ステップ 2:必要に応じて詳細設定を変更する
デフォルトでは、チェッカーは最新のデスクトップ版 Chrome の User-Agent で GET リクエストを送信し、Cookie は送らず、リダイレクトは 20 回までたどります。詳細設定で、これらを変更できます。
- HTTP メソッド:GET、HEAD、POST から選べます。HEAD は軽量ですが、サーバーによっては異なる応答を返すことがあり、レスポンスにボディがないためクライアントサイドリダイレクトを検出できません。POST は入力したリクエストボディを送信するもので、フォームの処理や API のテストに使います。以降のホップはブラウザーと同じルールに従います。POST の後、301 と 302 では GET として続行し、303 では常に GET になり、307 と 308 ではメソッドとボディが維持されます。
- 最大ホップ数:たどるリダイレクトの回数を 1〜50 の範囲で指定します。デフォルトの 20 は、Fetch Standard や Chrome、Firefox の上限と同じです。チェーンが Googlebot の上限内に収まるかを確認するには、10 に設定します。
- カスタム User-Agent:空欄の場合はデスクトップ版 Chrome として送信します。プリセットには、iPhone の Safari、Android の Chrome、Googlebot(スマートフォンとデスクトップ)、Bingbot、Facebook と X のリンクプレビュー用ボット、curl があります。
- カスタムリクエストヘッダー:すべてのホップで送信する追加のヘッダーです。たとえば
Accept-Language: fr-FRを指定すると、言語によるリダイレクトを発生させられます。 - Cookie:
name=value; other=valueの形式で入力すると、ログイン状態、Cookie への同意状態、地域の設定を再現できます。チェーンの途中で設定された Cookie は、ブラウザーと同じように以降のホップでも保持されます。 - クライアントサイドリダイレクト:meta refresh タグや単純な JavaScript リダイレクトを実際にたどるか、検出結果の報告だけにするかを選べます。
- SSL エラーを無視:Cloudflare のエッジは常に証明書を検証するため、この設定で壊れた証明書をスキップすることはできません。TLS エラーは、発生したホップで報告されます。
ステップ 3:結果を確認する
結果の先頭には、最終 URL とそのステータスコードが表示されます。その下のチェーンには、ホップごとに 1 行で次の情報が表示されます。
- リクエストした URL と、使用した HTTP メソッド
- ステータスコードとリーズンフレーズ(各コードの意味はステータスコードのリファレンスで解説しています)
- 応答時間(リクエストの送信からヘッダーの受信までの時間。DNS ルックアップや接続の確立にかかった時間も含みます)
- 転送先を示す
Location - レスポンスヘッダーと、そのホップで設定された Cookie の名前
各リダイレクトには、その発生方法を示すラベルが付きます。HTTP ステータスコード、meta refresh(遅延秒数付き)、JavaScript のいずれかです。検出したもののたどらなかったクライアントサイドリダイレクトも報告されます。同じくらい重要なのが、チェックがどのように終了したかです。
| 終了の種類 | 意味 |
|---|---|
| 最終レスポンス | 200 OK や 404 Not Found など、リダイレクトではないレスポンスにチェーンが到達しました。 |
| リダイレクトループ | 次のリクエストが、以前のリクエスト(同じ URL、メソッド、Cookie)の繰り返しになります。どのホップでループが閉じるかが結果に表示されます。 |
| ホップ数の上限に到達 | 上限に達した時点でも、チェーンがまだリダイレクトを続けていました。次の転送先は表示されますが、リクエストは送信されません。 |
| エラー | DNS、接続、TLS、タイムアウトのいずれかでホップが失敗したか、リダイレクト先が有効な URL ではないか、許可されていない URL でした。 |
警告は、チェーン内の一時的なリダイレクト、HTTPS から HTTP へのダウングレード、3 回を超えるリダイレクト、別ドメインにある最終 URL、クライアントサイドリダイレクト、ページのボディを読み取れなかった HEAD リクエストについて表示されます。
注意が必要な警告が 1 つあります。サイトによっては、自動化されたトラフィックやデータセンターからのトラフィックに対して、Cloudflare の「Just a moment...」ページのような、ボット対策のチャレンジページ(ボットかどうかを確認するページ)を表示します。そのように見えるレスポンスには、TrueURL がマークを付けます。チェックがたどり着いたのはリンク先ではなく、サイトの保護レイヤーだからです。実際の訪問者は、別の場所にたどり着く可能性があります。
コマンドラインでリダイレクトを確認する方法
curl は macOS、Windows 10 / 11、ほとんどの Linux ディストリビューションにプリインストールされており、ブラウザーのキャッシュを介さずに、サーバーが送信した内容をそのまま表示します。以下の例は Unix シェルを前提としています。Windows PowerShell 5.1 では curl が Invoke-WebRequest のエイリアスになっているため、curl.exe と入力し、/dev/null の代わりに NUL と書いてください。
1 つのホップを確認する
curl -I https://example.com/old-page-I は HEAD リクエストを送信し、ステータス行や Location を含むレスポンスヘッダーを表示します。curl は、指定しない限りリダイレクトをたどりません。HEAD を異なる方法で扱うサーバーもあるため、結果がおかしいと感じたら GET で確認し直してください。-o /dev/null でボディを破棄し、-D - でヘッダーを表示します。
curl -sS -o /dev/null -D - https://example.com/old-pageチェーン全体をたどる
-L を付けるとリダイレクトをたどり、-I または -D - と組み合わせると、curl はすべてのホップのヘッダーを表示します。grep で絞り込めば、簡潔に表示できます。
curl -sIL http://example.com/Shoes | grep -iE '^(HTTP/|location:)'HTTP/1.1 301 Moved Permanently
Location: https://example.com/Shoes
HTTP/2 301
location: https://www.example.com/Shoes
HTTP/2 302
location: /shoes/
HTTP/2 200curl はデフォルトで最大 50 回までリダイレクトをたどります。--max-redirs 10 を指定すると、Googlebot と同じ上限を適用できます。
最終 URL だけを表示する
-w(write-out)オプションは転送後に詳細を表示するため、curl を簡易的な短縮 URL 展開ツールとして使えます。
curl -sSL -o /dev/null -w '%{http_code} %{num_redirects} %{url_effective}\n' https://example.com/go%{url_effective} は最後に取得した URL、%{num_redirects} はたどったリダイレクトの回数、%{http_code} は最終的なステータスコードです。%{time_redirect} は、最後のリクエストの前にリダイレクトに費やした秒数を示します。-L を付けない場合は、%{redirect_url} で最初のリダイレクトの転送先を確認できます。
POST リクエストをテストする
-d はボディを送信し、リクエストを POST にします。このときリダイレクトをたどる curl はブラウザーと同じように動作し、301、302、303 の後は GET に切り替え、307 または 308 の後は POST とそのボディを再送信します。
curl -sSL -o /dev/null -D - -d 'email=test%40example.com' https://example.com/subscribe-X POST と -L の組み合わせは避けてください。-X はすべてのリクエストでメソッドを強制するため、ブラウザーなら GET に切り替える 301、302、303 の後も curl は POST を送り続けます。その結果、実際のクライアントでは起こりえないチェーンをテストすることになります。
User-Agent、ヘッダー、Cookie を変更する
# スマートフォンの User-Agent
curl -sIL -A 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Mobile/15E148 Safari/604.1' https://example.com/
# リクエストヘッダーを追加
curl -sIL -H 'Accept-Language: de-DE,de;q=0.9' https://example.com/
# Cookie を送信し、チェーンの途中で設定された Cookie を保持
curl -sSL -o /dev/null -D - -b 'consent=yes' -c cookies.txt https://example.com/-A で User-Agent を設定し、-H でヘッダーを追加し、-b で Cookie を送信します。-c は受け取った Cookie をファイルに保存するとともに curl の Cookie エンジンを有効にするため、あるホップで設定された Cookie が次のホップで送信されます。
curl は JavaScript を実行せず、meta refresh タグにも反応しません。curl の最後のレスポンスが 200 OK の HTML ページなのに、ブラウザーでは別のページにたどり着く場合は、クライアントサイドでリダイレクトが発生しています。
ブラウザーのデベロッパーツールでリダイレクトを確認する方法
デベロッパーツールでは、自分の Cookie、拡張機能、所在地が反映された、自分のブラウザーから見たとおりのチェーンを確認できます。
- デベロッパーツールを開き(F12 キー、Mac では Cmd+Option+I)、Network(ネットワーク)タブを選択します。
- Chrome と Edge では Preserve log(ログを保持)を、Firefox ではネットワーク設定メニューの Persist Logs をオンにします。オフのままだとページを読み込むたびに一覧が消去され、クライアントサイドリダイレクトが見えなくなります。
- Disable cache(キャッシュを無効化)をオンにします。キャッシュされたリダイレクトによって、サーバーが現在送信している内容が隠れてしまうのを防げます。
- アドレスバーに URL を入力します。
各ホップは、3xx のステータスとともに個別の行として表示されます。行を選択して Headers(ヘッダー)タブを開くと、location レスポンスヘッダーを確認できます。Chrome で Size(サイズ)列に「(disk cache)」や「(memory cache)」と表示されている場合、そのリダイレクトはサーバーではなくキャッシュから返されたものです。
Chrome では、http:// から https:// への 307 Internal Redirect が表示されることがあります。これはサーバーが送ったものではありません。ブラウザー自身がリクエストをアップグレードしたもので、通常はそのサイトの HSTS(HTTP Strict Transport Security)ポリシーを保存していることが理由です。暗号化されていない HTTP に対してサーバーが実際にどう応答するかを確認するには、curl か TrueURL を使ってください。
よくあるリダイレクトの問題と解決方法
1 ホップで終わらないチェーン
チェーンは層のように積み重なって伸びていきます。以前のサイト移転で作ったルールの転送先を、その後の移転でさらにリダイレクトしてしまう、といった具合です。すべてのルールが最終的なリンク先を直接指すようにし、内部リンク、canonical タグ、hreflang アノテーション、サイトマップも更新して、自分のサイト内でリダイレクトが発生しないようにしましょう。どの古い URL がまだ 2 ホップ以上を必要としているかは、リダイレクト一括チェッカーで確認できます。
リダイレクトループ
Chrome ではループが「リダイレクトが繰り返し行われました」(ERR_TOO_MANY_REDIRECTS)と表示され、Firefox では「ページの自動転送設定が正しくありません」と表示されます。主な原因は次のとおりです。
- プロキシや CDN の背後での HTTPS 化:オリジンサーバーは HTTP を HTTPS にリダイレクトしますが、プロキシが暗号化されていない HTTP でオリジンに接続するため、オリジンからは HTTPS のリクエストが一度も見えず、リダイレクトが永遠に続きます。Cloudflare では、SSL/TLS の暗号化モードを Flexible にしたときの典型的な症状です。Full (strict) を使うか、オリジン側で
X-Forwarded-Protoを確認するようにしてください。 - 2 つのレイヤーの食い違い:CDN のルールが
wwwを削除するのに、サーバーがそれを付け加える場合や、フレームワークが付けた末尾のスラッシュを CDN が取り除く場合などです。 - Cookie に依存するリダイレクト:ログインページや同意ページが訪問者を元の URL に戻しても、Cookie が保存されていないため、再びログインページにリダイレクトされます。
リダイレクトループチェッカーを使うと、どのホップでループが閉じるかがわかります。そのうえで、ルールごとに担当するレイヤーを 1 つに絞りましょう。
1 つのチェーン内での 301 と 302 の混在
301、302、200 と続くチェーンは、恒久的な移転の途中に一時的なステップが挟まっている状態です。これはデフォルト設定が原因であることが多く、Express の res.redirect() も PHP の header('Location: ...') も、指定しなければ 302 を送信します。すべてのホップで恒久的なステータスコードを使い、301 リダイレクトチェッカーで確認してください。どのコードがどのような場面に適しているかは、HTTP リダイレクトのステータスコードに関するガイドで解説しています。
HTTP → HTTPS → www の二重ホップ
非常によく見られるのが、http://example.com → https://example.com → https://www.example.com というチェーンです。1 ホップで済むところに 2 ホップかかっています。正規でない各バリエーションを最終的な HTTPS の URL に直接リダイレクトし、HTTPS リダイレクトチェッカーで 4 つすべてをテストしましょう。
ただし、意図的な例外が 1 つあります。正規ホストが www で、ドメインを HSTS プリロードリストに登録する場合、hstspreload.org は http://example.com をまず https://example.com にリダイレクトすることを求めています。ブラウザーに、www なしのドメインそのものの HSTS ポリシーを記録させるためです。
末尾のスラッシュの不統一
/pricing と /pricing/ は別の URL です。両方が 200 OK を返せば重複コンテンツになり、2 つのレイヤーが互いに相手へリダイレクトすればループになります。どちらか一方の形式に決め、もう一方は 1 回の 301 でそちらにリダイレクトし、リンクも統一しましょう。末尾スラッシュチェッカーなら、両方の形式を一度にテストできます。
モバイルだけで発生するリダイレクト
モバイル専用サイト、アプリのインストールを促す画面、デバイスの判定によって、スマートフォンだけが別の場所に転送されることがあります。多くの場合、対応するページではなく、モバイルサイトのトップページに飛ばされます。モバイルファーストインデックスのもとでは、Google は主にスマートフォン用クローラーでクロールするため、インデックス登録にとって最も重要なのはモバイルのチェーンです。モバイルとデスクトップのリダイレクト比較で両方を比べてみましょう。
サイトマップ内のリダイレクト
サイトマップには、検索結果に表示させたい正規 URL、つまり 200 OK を返す URL を記載します。リダイレクトするエントリはクロールのリクエストを無駄にし、正規 URL について矛盾したシグナルを送ってしまいます。サイト移転のたびにサイトマップリダイレクトチェッカーを実行し、リダイレクトするエントリはそれぞれの最終 URL に置き換えましょう。
JavaScript と meta refresh によるリダイレクト
Google は、即時の meta refresh を恒久的なリダイレクトとして扱い、遅延のあるものは一時的なリダイレクトとして扱います。JavaScript リダイレクトを Google が認識するのは、ページをレンダリングした後だけです。レンダリングはクロールの後に行われる処理で、失敗することもあります。ほかの多くのクローラーやリンクプレビュー用のボット、コマンドラインツールは JavaScript をまったく実行せず、中には meta refresh まで無視するものもあります。サーバーを管理できる場合は必ずサーバーサイドリダイレクトを使い、クライアントサイドリダイレクトは Meta Refresh チェッカーで見つけましょう。
リダイレクトのチェックリスト
サイト移転や CDN の変更の後、またキャンペーンの開始前には、次のリストを確認しましょう。
- すべての古い URL が、1 ホップで最終的なリンク先に到達している。
- 恒久的な移転では、すべてのホップで 301 または 308 を使っている。
- プロトコルとホストの 4 つのバリエーションすべてが、正規の HTTPS URL にたどり着いている。
- HTTPS から HTTP に切り替わるホップがない。
- UTM パラメーターやアフィリエイト ID を含むクエリ文字列が、チェーンを通過しても失われていない。
- 各 URL の末尾のスラッシュの形式が 1 つに統一され、もう一方の形式はそちらにリダイレクトされている。
- デスクトップ、スマートフォン、Googlebot のリクエストが、それぞれ同等のページにたどり着いている。
- 可能な限り、meta refresh や JavaScript の代わりにサーバーサイドリダイレクトを使っている。
- 内部リンク、canonical タグ、hreflang、サイトマップが最終 URL を指している。
- 代わりのページがない削除済みのページは、トップページにリダイレクトせず、404 または 410 を返している。
- サイト移転のリダイレクトを維持している。Google は少なくとも 1 年間維持することを推奨しています。