URLに”?”が入ると301リダイレクトがうまくできない場合の対処法

テクノロジー

.htaccessを使って、"?"を含むURLを別のページにリダイレクトする方法を記します。

301リダイレクトとは

このサイトのようにWordPressでWebサイトを作成している場合、古いサイトのページを新しいサイトに移す場合や、何らかの理由でURLを変更した際に、「自動で新しいURLにジャンプさせる」かつ「検索エンジンにもURLの変更を通知する」ために301リダイレクトを使用することがあります。

具体的には.htaccessファイルで指定したり、リダイレクト用のWordPressプラグインを利用します。詳しくはいろいろなサイトで解説されているので検索してみてください。

"?"が入るとなぜかリダイレクトできない

私の場合、古いサイトの特定のページだけを今の新しいサイトにリダイレクトさせようと考えていました。(2019/11/13追記:パーマリンクの設定を変更したので、今は形式が異なる)

  • 古いサイト:https://古いサイト.com/?p=123
  • 新しいサイト:https://新しいサイト.com/?p=456

WordPressでは、(テーマに依るかもですが)デフォルトでは上記のように?p=xxxという形式で終わるURLになります。SEO的には変えたほうが良いという話をよく見かけますが、ページのタイトルや内容が後で変わり得ることを考えるとURLをページの内容に過度に依存させたくなかったのと、変えるべきということを知った時点で既にある程度のページがあったので、変えたくなかったのです。

そこで、私は当初は.htaccessファイルを作成して、RewriteRuleで"?"が入ったURLをまるごと指定し、古いページだけ新しいページにリダイレクトするように正規表現を書いてみました。しかしどういうわけかリダイレクトされませんでした。正規表現の誤りかと思ってチェック用ツールで調べたりもしましたが、誤りは発見できませんでした(正規表現のエスケープ文字の指定ミスかとも思いましたが違った)。.htaccessではなくWordPressのリダイレクト用プラグインも試してみましたが結果は変わらず。

そこで、一歩離れて改めてURLを見てみると…ITエンジニアとしての知識からすると、URL内の"?"は、単なる呼び出し先ページetcではなくクエリパラメータとして扱われます。となると、通常のURLとは異なる扱いになっているのではないだろうか…?と思いました。

"?"が入る場合はQUERY_STRINGを使って指定する。

その線で調べてみると、確かにクエリとして扱われているようで、RewriteRuleでの正規表現RewriteCondの%{REQUEST_URI}では"?"の後ろは拾えていないようでした。クエリパラメータは%{QUERY_STRING}を使用すると拾えます。結果として、次のような内容を古いサイトの.htaccessに書くことで目的を達成できました。

RewriteEngine on
RewriteCond %{QUERY_STRING} p=123
RewriteRule ^ https://新しいサイト.com/\?p=456 [L,R=301]