リダイレクトチェーンの確認と修正方法(301/302)

リダイレクトチェーンとは、URLが最終目的地へ直接ジャンプせず、途中のURLを経由してから到達する状態のことです。http://example.com/pageが301でhttps://example.com/pageへ、さらに301でhttps://www.example.com/pageへと移され、そこでようやく200が返る——これがチェーンです。余分なホップ1つごとにHTTPのラウンドトリップが1回増えます。しかも各ホップはそれ自体がルールであり、壊れたり、移動の性質を誤って示したりする可能性を持ちます。このガイドでは、チェーンがSEOを損なう理由、無料のRedirect Chain Checkerでチェーンをホップごとに読む方法、そしてどんなチェーンでも1回のリダイレクトに平坦化する手順を解説します。

リダイレクトチェーンとは何か

リダイレクト——単なる3xxではなく、具体的には301、302、303、307、308のいずれかのレスポンス——は、「リクエストされたページは今はここにある」というメッセージをLocationヘッダーで伝えます。チェーンとは、このリダイレクトが2つ以上連なった状態です:

GET http://example.com/old-page
  301 → https://example.com/old-page
  301 → https://www.example.com/old-page
  301 → https://www.example.com/new-page
  200 ← final page

クライアントは、各URLを順番にリクエストしなければなりません。対してリダイレクトループは自分自身へ巡り戻る(A → B → A)もので、永遠に解決しません。ブラウザにはERR_TOO_MANY_REDIRECTSと表示されます。チェーンが意図的に作られることはまれです。移行は積み重なります——古いwww統一の上にHTTPS化、その上にリプラットフォーム——そして、誰も以前のルールを片付けません。

リダイレクトチェーンがSEOを損なう理由

レイテンシが複利で効いてくる。ホップごとに少なくとも1回のHTTPラウンドトリップがかかります。ホップ数に訪問者のラウンドトリップ時間を掛けてみてください。ホストをまたぐホップにはDNS解決に加えて新しいTCP/TLSハンドシェイクが発生し、同一ホストのホップなら接続を再利用できます。Googleのサイト移行ガイドは「リダイレクトの連鎖はユーザーのレイテンシを増やし、すべてのユーザーエージェントやブラウザが長いリダイレクトチェーンをサポートしているわけではない」と警告しています。しかもページ速度は、ランキングに使われるCore Web Vitalsのシグナルに反映されます。

存在しないURLにクロール予算が浪費される。中間URLを追うために使った1クロールは、本物のページに使えなかった1クロールです。チェーンをrobots.txtで解決しようとするのも禁物です。中間URLをdisallowすると、リダイレクト自体がGooglebotから隠れ、Googlebotにはホップの代わりにブロックが見えてしまいます。robots.txtは、本来のクロール制御の指示だけに留めましょう。

チェーンは壊れやすい。途中のホップが1つでも壊れると、その上流すべてが行き止まりになります。元のURLを指しているバックリンクも道連れです。

ステータスコードの混在は、シグナルの混在を生む。Googleのリダイレクトのドキュメントは明快です。301については「インデックス処理のパイプラインは、リダイレクト先を正規URL(canonical)とすべきだというシグナルとしてリダイレクトを使用する」。302については「リダイレクトをシグナルとして使用しない」ため、送り元のページが検索結果に残ります。チェーンのどこかに302があるだけで、統合が遅れたり妨げられたりします。Googleは、長期間置かれた302も最終的には恒久的として扱われる——ただしそれは遅い——とも述べています。ホップ自体は何も失いません。Googleのサイト移行ガイドいわく、「301およびその他の恒久的なリダイレクトはPageRankの損失を引き起こさない」のです。

301 vs 302 vs 307 vs 308:どれか1つを選び、その意味を貫く

  • 301(Moved Permanently)——永久に移動。移行、URL書き換え、http→https、www統一のデフォルト。
  • 302(Found)——一時的。古いURLが正規URLのまま残ります。A/Bテスト、短期プロモーション、ジオターゲティング向け。
  • 307 / 308——より厳格な一時・恒久コード。同じメソッドとボディをそのまま再送することが要求されます。

問題は組み合わせたときに始まります。何年も前に/old-lpから/spring-campaignへ301を設定した。今年、マーケティングが「ただのキャンペーンだから」と/spring-campaignを302で新ページへ向けてしまった。この301 → 302のチェーンは、恒久性を半分だけ主張している状態です。一度だけ決めましょう。恒久的なら——すべてのホップを301に。一時的なら——元のURLから1回だけ302を。

リダイレクトチェーンをステップごとに確認する方法

無料のRedirect Chain Checkerは、クローラーが見るのと同じ形でチェーンをたどります。各ホップは、キャッシュなし、Cookieなし、JavaScriptなし、HSTSによるアップグレードなしの、まっさらなHTTP GET——ユーザーエージェントはGeoToolsBot/1.0です。

ステップ1:テストする価値のあるURLを集める

推測ではなく情報源から集めます。現在および過去のサイトマップ、サーバーのアクセスログ、外部からリンクされているページならSearch Consoleのリンクレポート——Googleのサイト移行ガイドが勧める情報源と同じです——に加えて、主要ページのhttp://版と非www版、そしてバックリンクのエクスポート。

ステップ2:チェックを実行する

Redirect Chain CheckerにURLを貼り付けて、Check redirectsを押します。ツールは、リダイレクトを無効にした状態でそのURLをリクエストし、Locationを読み取り、解決して、またリクエストする——これを最大6ホップまで繰り返し、各ステップでループを検出します。結果には、各ホップのステータスバッジ、URLとターゲットに加え、最終ランディングページとコンテンツタイプが表示されます。私たちがテストした健全な参考例、http://github.com:301が1回、その後200。

ステップ3:問題リストを読む

チェッカーは、害になるものにもフラグを立てます。3ホップを超えるチェーン——Googleが「理想的には3ホップ以内、最大でも5ホップ未満に」と助言するのと同じ基準。1ホップ目以降もプレーンなhttp://のままのホップ——HTTPSアップグレードの遅れを意味します。恒久コードと一時コードの混在。クロスドメインのホップ——登録可能なドメイン(登録する単位。shop.example.comではなくexample.com)から出ていくホップで、Googleはこれをサイト移行として扱い、住所変更ツール(Change of Address)を含む独自のチェックリストの対象になります。PDFのようなHTML以外の最終ページ。そして4xx/5xxの最終ページ。循環するURLには、チェーンの代わりにループエラーが返ります。

ステップ4:スポットチェックのエンジニア流

curl -sI http://github.com          # first hop only
# HTTP/1.1 301 Moved Permanently
# Location: https://github.com/

curl -sIL http://www.apache.org     # headers for EVERY hop
# HTTP/1.1 301 Moved Permanently
# Location: https://www.apache.org/
# HTTP/2 200

curl -s -o /dev/null -w 'status=%{http_code} redirects=%{num_redirects} final=%{url_effective}n' -L http://github.com
# status=200 redirects=1 final=https://github.com/

私たちの実行で判明した注意点が2つ。-IはHEADリクエストを送りますが、HEADを特別扱いするサーバーがあります。実際、github.comはこちらのHEADでハングし、GETはすんなり通りました。また、最終が403でも、必ずしも壊れているとは限りません。執筆時点でstackoverflow.comは、きれいな301を返した後、ボットに403を返しました。「壊れた」最終ページは、まずブラウザで再確認しましょう。

チェーンを1ホップに平坦化する方法

目標は、リダイレクトするどのURLも、最終目的地を直接指すようにすることです。仲介役は要りません。

  1. まずチェーンをマッピングする。何かに手を付ける前に、正確なホップとステータスコードを書き出します。
  2. 最初のホップを書き換える。nginxなら、ポート80で待ち受けるserverブロック(または旧ホストのブロック)にreturn 301 https://www.example.com/new-page;を置きます。Apacheなら、Redirect 301 /old-page https://www.example.com/new-pageはmod_aliasを必要とし、vhostか.htaccessに記述します。このディレクティブはパスセグメント全体にマッチするため、/old-pageは/old-page/subも捕まえます。完全一致にするならRedirectMatch 301 ^/old-page$ https://…/new-page。WordPressなら、Redirectionプラグインがデータベース上でマッピングを管理します。
  3. 中間ホップを廃止するか、向き先を変える。ルールを削除する前に、実在するものがそこを指していないことを確認します。バックリンクのエクスポートを確認し、アクセスログをgrepしましょう。中間URLにまだ外部リンクが着地しているなら、その向き先も変えます。
  4. 内部リンクを修正する。リダイレクトは、自分では変更できないURL——他の人のバックリンク——のためのものです。自分のリンクは最終URLを直接指しましょう。内部リンクは、しばしばチェーンの最大の発生源です。
  5. 再チェックし、サイトマップを更新する。Redirect Chain Checkerで、適切なステータスの1ホップになっていることを確認します。次にサイトマップを再生成して最終URLだけを載せ、Search Consoleのサイトマップレポートから送信します。生成は無料のXML Sitemap Generatorで行えます。

httpとwwwを統一するケースでも、答えは1ホップです。各々が仕事を半分ずつこなす2つのルールにしてはいけません。http://example.comがhttps://www.…へ着く前にhttps://example.comを通される形、そして順序を誤ったforce-TLS/force-wwwルールが、典型的なループの原因です:

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}

もう1つの落とし穴。ルールの中には、クエリ文字列を黙って捨てるものがあります。Apacheのmod_aliasのRedirectはGETパラメータを引き継ぎますが、ターゲット自体に?を含むRewriteRuleは、[QSA]を付けない限り元のクエリ文字列を破棄します([QSD]は意図的に破棄するためのものです)。/?utm_source=newsletterのようなパラメータが剥がされたキャンペーンURLは、アナリティクスを壊します。UTMビルダーでリンクを作り、パラメータが生き残ることを確認しましょう。

避けるべきよくある間違い

  • 移行の積み重ね。http→https、その後www、その後リプラットフォーム——それぞれが前のリダイレクトの上に重なります。
  • 恒久的な移動に302を使う。理由は、CMSのデフォルトだったから。
  • ブラウザをテストとして信用する。ブラウザは301を積極的にキャッシュしますし、HSTSは最初のリクエストの前にhttpをhttpsへアップグレードします。実際に存在するより少ないホップ数が表示されることがあります。
  • 最初のホップだけ直す。中間ホップには今も、古いバックリンクからのリンクエクイティが届いています。
  • 「クロール予算を節約する」ために中間URLをrobots.txtでブロックする。Googlebotはリダイレクトを一切見られなくなります。
  • 同等のページではなく、手近なページへリダイレクトする。修正ではなく、単に短くなっただけです。

よくある質問

チェーン内のリダイレクトは何回から多すぎますか?

Googleのサイト移行ガイドでは、Googlebotは最大10ホップまで追跡するものの、目的地へ直接リダイレクトし、チェーンは「理想的には3ホップ以内、最大でも5ホップ未満」にしておくよう助言しています。チェッカーもこれに揃えており、3ホップ超でフラグを立て、6ホップで停止します。

301リダイレクトでPageRankは失われますか?

いいえ。Googleのサイト移行ドキュメントは「301およびその他の恒久的なリダイレクトはPageRankの損失を引き起こさない」と明記しており、GoogleのGary Illyesも2016年のツイートで同じことを述べています。それでもチェーンにはコストが残ります。レイテンシ、クロール予算、壊れやすいルール、そして統合を遅らせる一時コードです。

リダイレクトチェーンとリダイレクトループの違いは何ですか?

チェーンは最終的に実在するページへたどり着きます(A → B → C → 200)。ループは自分自身へ巡り戻る——A → B → A——もので、永遠に解決せず、ブラウザにはERR_TOO_MANY_REDIRECTSと表示されます。修正方法も異なります。ループに必要なのは、衝突しているルールを見つけて断ち切ることであり、1つのホップの向き先を変えることではありません。

なぜブラウザとチェッカーで異なるチェーンが表示されるのですか?

原因は2つの仕組みです。1つは、ブラウザのリダイレクトキャッシュ。とりわけ301は強力で、Chromeはルールが変わってから久しくても、キャッシュされたリダイレクトに従い続けます。もう1つはHSTSです。Strict-Transport-Securityヘッダーを受け取った(またはpreloadリスト経由の)ブラウザは、最初のリクエストの前にhttpをhttpsへアップグレードし、そのホップを見えなくします。チェッカーはHSTSリストを持たず、各URLを毎回まっさらな状態でリクエストします。

WordPressでリダイレクトチェーンはどう修正しますか?

大半は、プラグインのリダイレクト、.htaccess/nginxのルール、HTTPS/wwwのリライトの積み重ねが原因です。あらゆる情報源を洗い出しましょう——Redirectionプラグインのリダイレクト一覧とログ画面、サーバー設定、SEOプラグインのリダイレクト。そして各エントリを、元のURLが1回の301で最終目的地へ到達する形に書き換えます。内部リンクを更新し、チェッカーで再検証しましょう。

修正したリダイレクトをGoogleが認識するまでどれくらいかかりますか?

再クロールはURLごとに、Googlebotのペースで行われます。小〜中規模サイトなら通常数週間、大規模サイトならそれ以上です。Search ConsoleのURL検査でインデックス登録をリクエストし、更新したサイトマップを送信すれば、早められます。再処理中の変動は正常です。

古い301ルールはどのくらい残しておくべきですか?

Googleは、シグナルが引き継がれ、外部サイトがリンクを更新できるよう、リダイレクトを少なくとも1年——理想的にはそれ以上——残しておくことを推奨しています。削除する前に、残っているバックリンクがないこと(リンクのエクスポートで確認)、アクセスログに実トラフィックがないことを確認しましょう。

リダイレクトチェーンを一括で確認できますか?

無料チェッカーは1回の実行につき1URLです。サイト全体の監査には、Googleの移行ガイドが挙げているScreaming Frogなどのデスクトップクローラーでクロールし、3xxレスポンスをすべてエクスポートして、ルールを書き換える前に、問題の大きいものから順にチェッカーへ通しましょう。