Apache mod_rewrite 模块处理 query string的做法

1. 匹配所针对的URL部分

mod_rewrite的RewriteRule语法为:

RewriteRule Pattern Substitution [flags]

其中在Virtual Host中Pattern只匹配host和port之后的部分,query string也不属于匹配范围,例如,请求URL为http://www.mydomain.com:8080/myaction?param=123,那么pattern只针对/myaction这部分内容。

Substitution 用来替换成功匹配的URL;Flags是一些控制匹配的标志,标志之间用逗号隔开,例如R表示跳转(Redirect),L表示规则终止(Last)。

例如, 有如下的匹配规则:
RewriteRule ^/$ /default/myaction [R,L]

若请求URL为http://www.mydomain.com:8080/myaction?param=123,那么经过mod_rewrite会跳转(通过标志R)到http://www.mydomain.com:8080/default/myaction?param=123。注意,这里的query string完好无损。



2. 附加查询字符串标志(QSA)

如果现在需要在跳转的URL中添加一个查询参数userid=1,该怎么办?

首先看规则这样写行不行:

RewriteRule ^/$ /default/myaction?userid=1 [R,L]

答案是:不可以。如果这样写的话,跳转的URL会变成http://www.mydomain.com:8080/default/myaction?userid=1,注意这里把原始的查询参数param=123给丢掉了。

正确的写法是使用QSA标志:

RewriteRule ^/$ /default/myaction?userid=1 [QSA,R,L]

这样QSA标志表示在用户添加的查询参数后附加原有的查询参数,即跳转的URL为:http://www.mydomain.com:8080/default/myaction?userid=1&param=123。


3. 一个完整的例子

问题:如果用户输入的URL为http://www.mydomain.com:8080?phone=123,那么自动跳转到http://www.mydomain.com:8080/default/myaction_phone?company=1&phone=123;如果用户输入的URL为http://www.mydomain.com:8080,那么自动跳转到http://www.mydomain.com:8080/default/myaction?company=1。这里第一个跳转URL执行操作是myaction_phone,第二个跳转URL执行的操作是myaction。

答案:在Apache的虚拟主机配置中,可以这样写:

RewriteEngine on
RewriteCond %{QUERY_STRING} ^phone
RewriteRule ^/$ /default/myaction_phone?company=1 [QSA,R,L]
RewriteRule ^/$ /default/myaction?company=1 [R,L]

在这个配置中,RewriteCond只适用带QSA的第一条规则,因为这是规则链中的第一条也是最后一条规则(通过L标志),也就是说,只要查询字符串以phone开头,就应用第一条规则如果用户请求的URL不满足RewriteCond的条件,就使用第二条规则。


4. 总结
下面一段引用自Apache mod_rewrite文档(http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule)中的一段话,这段话基本上概括了mod_rewrite如何处理query string的问题:

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.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值