我正在尝试
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
我找不到从查询字符串中只删除一个变量的方法。我确信有一个简单的解决方案,但谷歌没有帮助。 感谢
答案 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]