Apache2:使用RewriteCond&RewriteRule在查询string中匹配重音字符的问题

在计划将URL从查询string格式移至基于数字的格式的网站上工作。 存在许多URL,其中有非转义的重音和类似的UTF8字符。 问题? 我似乎无法让Apache2正确匹配重音字符并重写。 我在Apache2configuration中完成了这一切。

例如,这个URL:

http://great.website.example.com/?place=cafe 

按照预期的这个Apache2 RewriteRule设置工作:

  RewriteCond %{QUERY_STRING} ^(place|location)=cafe RewriteRule ^/find/$ /find/1234? [L,R=301] 

现在看看这个url。 请注意重音符号:

 http://great.website.example.com/?place=café 

为什么这个URL不能用于下面的Apache2 RewriteRule设置:

  RewriteCond %{QUERY_STRING} ^(place|location)=café RewriteRule ^/find/$ /find/1234? [L,R=301] 

这两个规则都应该将URL重写为以下内容:

 http://great.website.example.com/find/1234 

但是带有重音符号的例子根本不起作用。 也许通配符会起作用,但我似乎无法得到这个工作。

你可以使用一个RewriteMap来为你做转换。 喜欢这个:

 RewriteMap unescape int:unescape RewriteCond %{QUERY_STRING} (location|place)=(.*) RewriteCond ${unescape:%2} café RewriteRule ^/find/$ /find/1234? [L,R] 

在第二个RewriteCond行我使用%2,因为%1将包含“位置”或“地点”。

但是,为了将单词映射到数字,将大量的RewriteRules添加到您的configuration中将成为您的服务器上的一个很大的性能下降,并且将难以维护。 更好的解决scheme是使用RewriteMap。

例如,假设/etc/apache2/places.txt包含:

 café 1234 shop 1235 ... 

那么这对你有用:

 RewriteMap unescape int:unescape RewriteMap places txt:/etc/apache2/places.txt RewriteCond %{QUERY_STRING} (location|place)=(.*) RewriteCond ${unescape:%2} (.*) RewriteRule ^/find/$ /find/${places:%1}? [L,R] 

您也可以使用基于数据库查询的RewriteMap。 这将是我的首选,因为我可以将字词与数字匹配的工作加载到内容pipe理系统。

更多细节可以在文档中find: http : //httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

你的/?place=café会被浏览器的url编码到/?place=caf%C3%A9 ,这就是你应该匹配的。

在一个相关的问题中 ,有人build议使用RewriteMap来调用外部程序来重写URL。

另外:也许请求实际上是完全不同的东西? 浏览器可能已经在内部将重音字符转换为url编码的ASCII码了? 例如' %20 '而不是' ”。