.htaccess でGETパラメータを維持したままリダイレクト

.htaccess でGETパラメータを維持したままリダイレクトする方法をメモ。

コード

RewriteEngine On

RewriteCond %{QUERY_STRING} (.*)$
RewriteRule ^(.*)$ https://redirected.example.jp/$1?%1 [R=303,L]

こんな感じでOK。

RewriteCondQUERY_STRING を使ってGETパラメータを取得しています。 RewriteCond の条件に一致した文字列はパーセント始まりの変数に収められるので、 RewriteRule のリダイレクト先URLに ?%1 と付けることで引き継いでいます。

ちなみにリダイレクト先URLに ? が決め打ち的に付いていますが、GETパラメータがない場合は自動的に ? は削除されるようです。例えば、 https://origin.example.jp/hoge.htmlhttps://redirected.example.jp/hoge.html? ではなく、 https://redirected.example.jp/hoge.html にリダイレクトされる、と言った具合です。

そのため、 RewriteCond の条件でも (.+)$ とはせず、 (.*)$ で「0文字以上」としています。

引っかかった場所

さて、処理自体はこれでOKだったのですが、別の場所で引っかかりました。

というのも、検証するのに適切な場所が思い付かなかったので、最初サブディレクトリで試験していました。

条件として、

  • https://origin.example.jp/fuga/ をルートとする
  • .htaccesshttps://origin.example.jp/fuga/.htaccess に配置
  • https://origin.example.jp/fuga/index.html にアクセスする

このような場合に、 https://origin.example.jp/fuga/hoge.htmlhttps://redirected.example.jp/hoge.html にリダイレクトされて、ディレクトリパス fuga/ が消えるという現象が発生します。

後で考えてみればサブディレクトリをルートとして、そこに配置した .htaccess の判定なのでディレクトリパスは吹っ飛びますよね……という単純な話だったのですが、気付かずにしばらく悩んでいました……。

参考

.htaccess

GETパラメータを引き継ぐ

RewriteRuleのフラグ, RewriteCondの変数

サブディレクトリ

(未使用) AcceptPathInfo

(未使用) 親ディレクトリの設定を引き継ぐ

(未使用) 内部転送と外部転送

正規表現

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。