WordPress が黙って行っていた転送を、止める前に洗い出す方法

「x-redirect-by: WordPress」は、WordPress が PHP の中で転送した時に付く応答の見出しです。.htaccess に転送の行が無いのに古い URL が転送されていたら、正体は WordPress 自身。止めると全部消えるので、curl で見分けて .htaccess に書き直した手順です。

WordPress を止めると消える転送の例を並べた画像

「x-redirect-by: WordPress」とは、WordPress が PHP の中で転送(リダイレクト)した時に、応答に付ける見出しです。.htaccess に転送の行が無いのに古い URL が転送されていたら、転送しているのは WordPress 自身で、WordPress を止めた瞬間にすべて消えます。curl で見出しを確かめて洗い出し、止める前に .htaccess の RewriteRule に書き直しました。

会社のサイトを WordPress から静的なサイトへ移す準備をしていた時のことです。古い URL の転送の一覧を作っていて、おかしなことに気づきました。

アプリのプライバシーポリシーの古い URL(/talklens/privacy/ など)を開くと、ちゃんと新しい /privacy/ へ転送されます。ところが、サーバーの .htaccess を見ても、転送の行は1つもありません。書いてあったのは、WordPress が自動で書く「ファイルが無ければ index.php へ渡す」という数行だけでした。

転送していたのは、WordPress 自身でした。ということは、WordPress を止めた瞬間に、この転送はすべて消えます。この記事は、そうした「WordPress が黙って行っていた転送」を、止める前に洗い出して .htaccess に書き直した記録です。

転送の持ち主を見分ける:x-redirect-by

転送が .htaccess(サーバー)から来ているのか、WordPress から来ているのかは、応答の見出しで見分けられます。WordPress が PHP の中で転送する時は、「x-redirect-by: WordPress」という見出しを付けて返します。

Macで実行
curl -sI https://あなたのドメイン/talklens/privacy/ | grep -iE '^(HTTP|location|x-redirect-by)'

ここで x-redirect-by: WordPress が出たら、その転送は WordPress がしています。.htaccess の RewriteRule による転送には、この見出しは付きません。

止める前は .htaccess に転送の行が無く、WordPress(PHP)が 301 を返していた。止めた後は .htaccess の RewriteRule が 301 を返すことを示した図
転送の持ち主が WordPress なら、止める前に .htaccess へ移しておく必要がある
ターミナルの再現。curl で応答の見出しを見ると、301 と転送先のほかに x-redirect-by: WordPress が付いている。表示は見本
x-redirect-by: WordPress が出たら、WordPress の転送

WordPress がしていた転送は4種類あった

調べていくと、WordPress が黙って行っていた転送は、大きく4種類ありました。どれも、WordPress の設定画面で自分で作った覚えのないものです。

線路が交差する分岐点を、上から写した写真
転送は、行き先ごとに4種類に分けた(イメージ写真)

1. www 付きから www なしへの転送

https://www.ドメイン/ を開くと、www なしのアドレスへ転送されていました。WordPress は、設定にある「サイトのアドレス」と違うホスト名で開かれると、設定のアドレスへ転送します。サーバーの設定ではなかったので、WordPress を止めると www 付きのアドレスはそのまま新しいサイトを表示し、同じページが2つの住所で見える状態になります。

2. 似た名前のページへの自動の転送

存在しない URL を開かれた時、WordPress は「名前の似たページ」を探して、見つかればそこへ転送します。/talklens/privacy/ が /privacy/ へ転送されていたのは、これでした。私たちが意図して作った転送ではありませんが、アプリの中のリンクには、こうした古い URL を向いているもの(Shade Preview の /shade-preview/privacy/)があり、結果として大事な転送になっていました。

3. ?p= の短い URL

WordPress のページには、?p=番号 という短い URL もあります。ページの番号は、ページの HTML の中にある shortlink(短いリンク)にも書かれています。短い URL で開くと、WordPress がそのページの URL へ転送します。

4. URL の書き方のゆれ

末尾の / が無い URL などを、WordPress が正しい形へそろえて転送することもあります。静的なサイトでは、フォルダの URL の末尾に / を付ける転送を、自分で書く必要があります。

WordPress が黙って行っていた4種類の転送の図。www の統一、似た名前のページ、?p= の短い URL、URL の書き方のゆれ
WordPress がしていた4種類の転送

洗い出しの手順

WordPress が黙って行っていた転送の洗い出しの手順。開かれる可能性のある古い URL を集め、curl で1つずつ開いて転送の持ち主を見て、?p= の番号を調べ、行き先を決めて一覧にする
止める前に、4つの手順で洗い出す
  1. 開かれる可能性のある古い URL を集める

    WordPress が作る wp-sitemap.xml に載っている URL、トップページのリンク、アプリの中から開くリンク(プライバシーポリシーやサポートのページ)を集めます。アプリのリンクは、アプリの設定画面やストアの情報から拾います。

  2. 1つずつ curl で開き、転送の持ち主を見る

    集めた URL を、www 付き・http・末尾の / のあり無しの形でも開き、応答の番号、転送先、x-redirect-by の有無を記録します。

    Macで実行
    for u in /talklens/privacy/ /kaitori-base/privacy/ /shade-preview/privacy/; do \
      printf '%s ' "$u"; curl -s -o /dev/null -D - "https://あなたのドメイン$u" \
      | grep -iE '^(location|x-redirect-by)' | tr -d '\r' | tr '\n' ' '; echo; done
  3. ?p= の番号を調べる

    外から短い URL で開かれていそうなページは、HTML の中の shortlink で番号を調べ、?p=番号 で開いて転送先を確かめます。

    Macで実行
    curl -s https://あなたのドメイン/ページ/ | grep -o "rel=['\"]shortlink['\"][^>]*"
  4. 行き先を決めて、一覧にする

    古い URL ごとに、新しいサイトでの行き先を決めます。プライバシーポリシーの3つは、ただ /privacy/ へ送るのではなく、新しいページの中の各アプリの付録の位置(/privacy/#talklens など)へ送ることにしました。

.htaccess に書き直す

洗い出した転送を、新しい .htaccess に1つずつ書きました。前の記事に書いたとおり、この .htaccess は Mac の Apache で試してから使っています。

オレンジ色の「DETOUR」と矢印の標識の写真
止める前に、転送を書き直しておく(イメージ写真)
洗い出した転送を新しい .htaccess の RewriteRule に1つずつ書き直す。転送先に # を含む時は NE を付け、WordPress の似た名前を探す転送は全部まねせず実際に開かれる URL だけを書く
WordPress の転送を、.htaccess に引っ越す
.htaccess
RewriteEngine On

# 1. www 付きを www なしへ
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

# 2. アプリのプライバシーポリシーの古いURL を、付録の位置へ(NE は # をそのまま使うため)
RewriteRule ^talklens/privacy/?$ https://example.com/privacy/#talklens [R=301,NE,L]

# 3. 番号の分かっているページの短いURL を、そのページへ(?以降は消す)
RewriteCond %{QUERY_STRING} (^|&)(p|page_id)=268(&|$)
RewriteRule ^(index\.php)?$ https://example.com/talklens-support/ [R=301,QSD,L]
# ほかの ?p= などは、?以降を消したトップへ
RewriteCond %{QUERY_STRING} (^|&)(p|page_id|cat|author|m)=[0-9]
RewriteRule ^(index\.php)?$ https://example.com/ [R=301,QSD,L]

# 4. 実在するフォルダの URL に、末尾の / を付ける
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ https://example.com/$1/ [R=301,L]

止めたあとに確かめる

WordPress を止めたあと、同じ URL をもう一度 curl で開きました。転送が同じ行き先へ返っていること、そして x-redirect-by: WordPress が出なくなったこと(転送の持ち主が .htaccess に移ったこと)を確かめます。

WordPress を止めたあと、同じ URL を curl でもう一度開き、転送が同じ行き先へ返っていることと、x-redirect-by: WordPress が出なくなったことを確かめる
転送の持ち主が .htaccess に移ったことを確かめる
Macで実行
curl -s -o /dev/null -D - https://asteroid-technology.com/talklens/privacy/ | grep -iE '^(HTTP|location|x-redirect-by)'
HTTP/2 301
location: https://asteroid-technology.com/privacy/#talklens
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' https://www.asteroid-technology.com/
301 https://asteroid-technology.com/
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' 'https://asteroid-technology.com/?p=268'
301 https://asteroid-technology.com/talklens-support/

まとめ

WordPress は、私たちが設定画面で作った覚えのない転送を、いくつも黙って行っていました。止める前にやることは、次の3つです。

WordPress が黙って行っていた転送を、止める前に洗い出す方法:要点のまとめ。開かれる可能性のある古い URL を集め、www・http・末尾の / のゆれも含めて curl で開く
この記事の要点
  • 開かれる可能性のある古い URL を集め、www・http・末尾の / のゆれも含めて curl で開く
  • x-redirect-by: WordPress の見出しで、転送の持ち主を見分ける
  • WordPress がしていた転送を、行き先を決め直して .htaccess に書き、止めたあとにもう一度開いて確かめる

移行の全体の流れは、こちらの記事にまとめています。

新しいトップページの画面と「WordPress → 静的サイト」の文字ホームページ制作WordPress から静的サイトへ、社名で検索1位を守ったまま移行した全手順会社のサイトを WordPress から静的サイト(HTML のファイルを置くだけのサイト)へ移した全手順です。社名で検索1位を守るための 301 リダイレクトの洗い出し、バックアップ、誰にも見せないリハーサル、表示を止めない切り替えの順番、すぐ戻せる作りまでを、実際の手順書から書きます。

この記事は、AI(Claude)の支援を受けて作成し、筆者が内容を確認しています。

  • WordPress
  • 301リダイレクト
  • .htaccess
  • x-redirect-by
  • curl

関連する記事

この記事に関連するサービス・アプリ

ブログの一覧へ