mod_rewrite删除一个GET变量

时间:2011-10-13 15:37:25

标签: apache mod-rewrite get

我正在尝试

  

example.com/home?lang=fr&foo=bar

并重定向到

  

example.com/fr/home?foo=bar

我试过

    RewriteCond %{QUERY_STRING} lang=([a-z]{2})&?
    RewriteRule ^(.*) /%1/$1 [R=307]

但是我得到了一个重定向循环。 这是因为在将“fr”移动到请求字符串的前面之后,lang = fr不会从查询字符串中删除。这导致:

  

example.com/fr/fr/fr/fr/fr/fr/fr/fr/fr /....

我可以用

    RewriteRule ^(.*) /%1/$1? [R=307]

但是这也会从我想保持原样的查询字符串中删除foo = bar

我找不到从查询字符串中只删除一个变量的方法。我确信有一个简单的解决方案,但谷歌没有帮助。 感谢

2 个答案:

答案 0 :(得分:5)

补充@whoisgregg的答案(+1),这是一个很好的改编自apache wiki。那里的规则并不完美(例如,这个页面上的查询字符串的访问控制不会在一个小的urlencoding上抵制)。

我们为测试用例提供了一个可行的解决方案,但某些扩展测试可能会失败:

RewriteCond %{QUERY_STRING} ^(.*)lang=([a-z]{2})&?(.*)$
RewriteRule (.*) /%2/$1?%1%3 [R=307]

foo.php?foo=bar&novlang=fr&toto=titi => /fr/foo.php?foo=bar&novtoto=titi

此处检测到lang=部分,但如果任何参数以 lang 结尾,则会出现问题。

所以,我们需要一些修复,本周我一直在研究这个问题,而且我认为这是一个更好的版本:

RewriteCond %{QUERY_STRING} (.*)(^|&|%26|%20)lang(=|%3D)([^&]+)(.*)$
RewriteRule (.*) /%4/$1?%1%5 [R=307]

foo.php?foo=bar&novlang=fr&toto=titi => not matched (normal, no lang=)
foo.php?foo=bar&lang=fr&toto=titi&b=a => fr/foo.php?foo=bar&toto=titi&a=b

这里唯一的问题是lang可能是部分或完整的url编码并且不会被检测到,但这是一种罕见的情况。我alos删除了对lang值只有2个字符的控制。我认为([^&]+)更好,它意味着所有字符,直到我匹配&

答案 1 :(得分:2)

这是apache wiki技术的一种变体,应该可以解决这个问题:

RewriteCond %{QUERY_STRING} ^(.*)lang=([a-z]{2})&?(.*)$
RewriteRule (.*) /%2/$1?%1%3 [R=307]