mod_rewriteでクエリ文字列(/?q=)を引き継がずにURL置換
mod_rewriteで単純にURLの置換を行って、
URL転送を行うと置換前のURLに付加されていたクエリ文字列が、
転送先のURLの末尾にも付加されてしまいます。
置換先ではクエリ文字列に合わせて、ディレクトリへ転送するような場合には、
クエリ文字列は邪魔になりますので、公式の手順で取り除くといいでしょう。
mod_rewriteでクエリ文字列(/?q=)を引き継がせない
mod_rewriteで単純にURLの置換処理を行ってURL転送を行うと、
以下のようにクエリ文字列がそのまま転送先に対しても付加されます。
基本URL転送とクエリストリング
以下の例では .htaccessに対して以下のように記述しています。
1 2 3 4 5 |
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule .* http://redirect.trce.info/ [R=301,L] </IfModule> |
実際の転送例
実際にアクセスするとリダイレクトが行われて、
転送先に対しても「?s=keyword」が付加されているのが確認できます。
http://q-modrewrite.trce.info/querystring/?s=keyword
転送先は以下のようになります。
http://redirect.trce.info/?s=keyword
この動作が基本です。
これでは困る場合もあるはずです。
例えば、
http://q-modrewrite.trce.info/querystring/?s=keyword にアクセスがあったら、
http://redirect.trce.info/categories/keyword/ へ転送したいような場合です。
このような場合も、そのまま記述すると、
http://redirect.trce.info/categories/keyword/?s=keyword として転送されてしまいます。
クエリストリングを消す場合の公式アナウンス
クエリストリングを引き継ぎたくない場合の対応は、
公式ヘルプに明記されています。
mod_rewrite – Apache HTTP Server Version 2.2 (抜粋引用)
Modifying the Query String
By default, the query string is passed through unchanged.
You can, however, create URLs in the substitution string containing a query string part.
Simply use a question mark inside the substitution string to indicate that the following text should be re-injected into the query string.
When you want to erase an existing query string, end the substitution string with just a question mark.
To combine new and old query strings, use the [QSA] flag.(微妙訳)
クエリ文字列を変更する
デフォルトでは、クエリ文字列は変更されずに通過させます。
しかしながら、URL内の置換文字列はクエリ文字列を含んで作成することができます。単に以下のテキストが問合わせ文字列に再吹き込まれなければならないことを示すために、置換文字列の中に疑問符を使ってください。
既存のクエリ文字列を消去したいときは、疑問符のみで置換文字列を終了します。
新旧のクエリ文字列を結合するには、[QSA]フラグを使用します。
上記の公式アナウンスを実際に例示します。
固定でクエリ文字列を指定する
以下のように.htaccessに対して指定します。
置換文字列内に「?q=custom」として固定のクエリ文字列を含んでいます。
RewriteRule .* http://redirect.trce.info/?q=custom [R=301,L]
1 2 3 4 5 |
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule .* http://redirect.trce.info/?q=custom [R=301,L] </IfModule> |
実際の転送例
実際にアクセスするとリダイレクトが行われて、
転送先に対しては「?s=keyword」ではなく「?q=custom」付加されているのが確認できます。
http://q-modrewrite.trce.info/querystring_custom/?s=keyword
転送先は以下のようになります。
http://redirect.trce.info/?q=custom
転送先URLの指定で個別に固定のクエリ文字列を指定した場合には、
転送元の要求URLにクエリ文字列が含まれていても、
転送先URLに対してはクエリ文字列の付加は行われません。
この仕組みがクエリ文字列の削除(消去)に利用できます。
既存のクエリ文字列を消去する
この投稿の本題です。
クエリ文字列を削除するには「置換文字列の最後をクエスチョンマークにする」と、
書かれています。
以下のように.htaccessに対して指定します。
置換文字列内に「?」としてクエスチョンマークのみを付加しています。
RewriteRule .* http://redirect.trce.info/? [R=301,L]
1 2 3 4 5 |
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule .* http://redirect.trce.info/? [R=301,L] </IfModule> |
実際の転送例
実際にアクセスするとリダイレクトが行われて、
転送先に対しては「?s=keyword」が削除されたURLとして転送されます。
http://q-modrewrite.trce.info/querystring_del/?s=keyword
転送先は以下のようになります。
新旧のクエリ文字列を結合する
では新旧のクエリ文字列を結合する場合とはどのようなケースでしょうか。
ここでは「?q=custom」を新しいクエリ文字列として利用します。
旧クエリ文字列は、これまで通り「?s=keyword」として要求URL側で指定します。
置換文字列内に「?q=custom」として固定のクエリ文字列を含んでいます。
RewriteRule .* http://redirect.trce.info/?q=custom [QSA,R=301,L]
クエリ文字列を転送先URLに対して付加するフラグとして、
QSAを追加しています。
このQSAを付加すると、本来クエリ文字列が削除されるような、
クエリ文字列(?)を含む置換指定であっても、
転送先URLに対して、元の置換文字列が付加されて生成されます。
1 2 3 4 5 |
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule .* http://redirect.trce.info/?q=custom [QSA,R=301,L] </IfModule> |
実際の転送例
実際にアクセスするとリダイレクトが行われて、
転送先に対しては「?s=keyword」ではなく「?q=custom」付加されているのが確認できます。
http://q-modrewrite.trce.info/querystring_join/?s=keyword
転送先は以下のようになります。
置換文字列内に指定したクエリ文字列の後ろに「&」が付加されて、
要求されたURLで指定されていたクエリ文字列が付加されています。
http://redirect.trce.info/?q=custom&s=keyword
これが[QSA]フラグの利用方法です。
公式ヘルプでは以下のように記載されています。
RewriteRule Flags – Apache HTTP Server Version 2.2 (引用抜粋)
QSA|qsappend
When the replacement URI contains a query string, the default behavior of RewriteRule is to discard the existing query string, and replace it with the newly generated one. Using the [QSA] flag causes the query strings to be combined.
Consider the following rule:
RewriteRule /pages/(.+) /page.php?page=$1 [QSA]
With the [QSA] flag, a request for /pages/123?one=two will be mapped to /page.php?page=123&one=two. Without the [QSA] flag, that same request will be mapped to /page.php?page=123 – that is, the existing query string will be discarded.
さいごに
本来はクエリ文字列をそのまま使う場合には何も意識する必要はありません。
クエリ文字列を引き継ぎたくない場合には「?」を末尾に付与します。
新旧を混在させて、旧クエリ文字列が必要な場合には[QSA]フラグを利用するといいでしょう。
ここでは置換元URLから置換先URLに対しての、
クエリ文字列の引継ぎについてご紹介しました。
ただ、そのまま引き継がれては面倒な場合もあることと思います。
そんな時には、クエリ文字列の一部を元にして、
新たな置換文字列を組み立てるような記述方法を利用するといいでしょう。
Apache,Apache Hadoop,Apache Subversion,Hadoop,HDFS,HBase,Hive,Mahout,Pigは、
Apache Software Foundationの米国およびその他の国における登録商標または商標です。
ApacheソフトウェアはApache Software License (原文)および
Apache License, 2.0 (原文)に基づきOpen Source Initiativeに承認されライセンスされています。
公開日:
最終更新日:2014/12/16