あーかいぶすハイディフィニション

ここはもう更新しとらんのじゃ

URL クエリのリダイレクト

URL クエリ、所謂 index.html?place=test&toilet=unko みたいな?入りの URL をリダイレクトさせたかったんだけどうまくいかなかったお話。


クエリ文字列(クエリストリング)とは - IT用語辞典 e-Words

動的なウェブアプリケーション開発してら一度は見てますね。んで、今回は以下のようにしたけど動かなかったってやつ。

Redirect index.html?place=test&toilet=unko http://example.com/unko.html

こう書いた .htaccess を RailsRoot/public に設置したんだけど、どうしても「index.html?place=test&toilet=unko」にアクセスしてうんこもらしちゃう。アクセスログにもバッチリ遷移前の URL にアクセスしてる履歴が、よくわかんねえな?と思って調べてたら以下のページを発見。

クエリ文字列(URLパラメタ)があるURLでのmod_rewriteの使い方 - hogehoge foobar Blog Style5

わーおまじで?ということでこう書けばいい。

RewriteEngine On
RewriteCond %{QUERY_STRING} place=test&toilet=unko
RewriteRule ^index.html http://example.com/unko.html [L]

見ればわかるけど、 RewriteCond のとこに %{QUERY_STRING} に続いて、遷移前の URL の ? 以降の部分を記述。RewriteRule の最初の引数に、遷移前の URL の ? 以前の部分を、次の引数は、遷移させたい URL を。最後の [L] は「条件を満たしたらこれ以下の条件は評価しない」だったはず、たぶんそう。

これで動きました。うんこもらせます。あーつかれた、ほんとうに困りますよ〜。

2015/01/03 追記
なんか RewriteRule 複数書いたらちゃんと評価されないでやんの。こんな仕様だっけ?

RewriteEngine On
RewriteCond %{QUERY_STRING} place=test&toilet=unko
RewriteRule ^index.html http://example.com/unko.html [L]
RewriteRule ^sp/index.html http://example.com/sp/unko.html [L]
  1. http://example.com/index.html?place=test&toilet=unko にアクセスしたら「http://example.com/unko.html
  2. http://example.com/sp/index.html?place=test&toilet=unkoにアクセスしたら「http://example.com/sp/unko.html

に遷移して欲しかったのに、 1. のほうは想定した動作だったけど、 2. の方がなぜかアドレスに「sp/index.html」で始まっていれば、どんな URL でも「http://example.com/sp/unko.html」につれていかれちゃう。 toilet=women とかでもうんこに連れて行かれるとかやめちくりー。フラグ [L] だから、一つ目の RewriteRule にマッチしなかったら、次の RewriteRule に処理が移るのはいいとして、その処理は RewriteCond で評価済みなんじゃないの?なんで評価されてねーんだよ!
という訳で、以下のようにいちいち RewriteCond をいっぱい書くことで回避しました。

## ignore URL /sp/
RewriteEngine On
RewriteCond %{QUERY_STRING} place=test&toilet=unko
RewriteRule ^index.html http://example.com/unko.html [R,L]

## include /sp/
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/sp/
RewriteCond %{QUERY_STRING} place=test&toilet=unko
RewriteRule ^sp/index.html http://example.com/sp/unko.html [R,L]

うーんこういう使い方であってんのか?わしはただリダイレクトしたいだけなんだ、Redirect で URL クエリだのなんだの言わず全部一致したら飛ばすみたいな処理受け付けてくれればそれで解決だったんだけど……なんでだめなんじゃろ。
あっちなみにこっそり RewriteRule のフラグを R,L にしていますが、追加した R はリダイレクトの意味だそうです。第二引数の結果に置換した URL にブラウザの表示も書き換えてくれるらしいですよ。なんか R=302 とかステータスも一緒に追加できるらしいけど詳しくはわからぬ。