我看到帖子 validating utf-8 in htaccess rewrite rule我认为这很好,但我首先遇到了一个更根本的问题:
我需要扩展以处理查询字符串参数、目录名称、文件名称以及用于向用户显示等的 utf-8 字符。
我用 DefaultCharset utf-8 配置了我的 Apache,如果重要的话还配置了我的 php。我原来的重写规则过滤除了常规 A-Za-z 和下划线和连字符之外的所有内容。它奏效了。其他任何东西都会给你一个 404(这就是我想要的!)现在,似乎一切都匹配,包括我不想要的东西,但是,尽管它似乎匹配但它不会进入查询字符串,除非它是一个普通的 A-Za-z_- 字符串。
我觉得这很令人困惑,因为规则说将您匹配的任何内容放入查询字符串中:
这是原始规则:
RewriteRule ^/puzzle/([A-Za-z_-]+)$ /puzzle.php?g=$1 [NC]
这是修改后的规则:
RewriteRule ^/puzzle/(\w+)$ /puzzle.php?g=$1 [NC]
我做了这个改变,因为我在某处读到\w 与 A-Zetc 中的所有字母字符匹配。只匹配没有口音和东西的那些。
我使用这些规则中的哪一个似乎并不重要:这是发生的事情:
在应用程序中我有这个:
echo $_GET['g'];
如果我给它一个类似 http://mydomain.com/puzzle/USA 的 url它呼应了“美国”并且工作正常。
如果我给它一个类似 http://mydomain.com/puzzle/México 的 url它对此没有回应,并警告我索引 g 未定义,当然也没有获得墨西哥的资源。
如果我给它一个类似 http://mydomain.com/puzzle/fuzzle/buzzle/j.qle 的 url它做同样的事情。
最后一个案例应该是 404!
无论我使用上述哪条规则,它都会执行此操作。我配置了重写日志
RewriteLogLevel 5
RewriteLog /opt/local/apache2/logs/puzzles.httpd.rewrite
但它是空的。
这是来自常规访问日志(状态为 200)
[26/May/2010:11:21:42 -0700] "GET /puzzle/M%C3%A9xico HTTP/1.1" 200 342
[26/May/2010:11:21:54 -0700] "GET /puzzle/M/l.foo HTTP/1.1" 200 342
我该怎么做才能将这些 $%#$@(*#@!!! 字符而不是斜杠、点或其他非字母字符放入我的程序中,一旦出现,它会正确解码它们吗??? posix char 类工作得更好吗?还有什么我需要配置的吗?
最佳答案
我建议您激活 MultiViews 而忘记 mod_rewrite。在相关的 Directory
/VirtualHost
部分添加到您的 apache 配置:
Options +MultiViews
#should already be set to this, but it doesn't hurt:
AcceptPathInfo Default
不,只要客户端在其 Accept header 中包含相应的 MIME 类型,您始终可以省略扩展名。
现在 /puzzle/whatever
的请求将映射到 /puzzle.php
并且 $_SERVER['PATH_INFO']
将被填充使用/whatever
。
如果你想用 mod_rewrite 做它也是可能的。 RewriteRule
的测试字符串未转义(%xx 部分被转换为它们代表的实际字节)。您可以使用 %{REQUEST_URI}
或 %{THE_REQUEST}
获取原始转义字符串(最后一个还包含 HTTP 方法和版本)。
按照惯例,网络浏览器在 URL 中使用 UTF-8 编码。这意味着“México”将被 urlencode 为 M%C2%82xico
,而不是 M%82xico
,如果浏览器使用 ISO-8859-1,这将是预期的。此外,[a-zA-Z]
将不匹配 é
。但是,这应该有效:
RewriteCond %{REQUEST_URI} ^/puzzle/[^/]*$
RewriteRule ^/puzzle/(.*)$ /puzzle.php?q=$1 [B,L]
您需要 B
来转义反向引用,因为您在查询字符串中使用它,其中允许的字符集小于 URI 的其余部分。
您应该注意的是 RewriteRule
不支持 unicode。 .*
以外的任何内容都可能给出(可能)不正确的结果。甚至 [^/]
也可能不起作用,因为 /
“字符”(读取:字节)可能是多字节字符序列的一部分。如果 RewriteRule
是 unicode 感知的,那么您使用 \w
的解决方案应该可以工作。
由于您不想匹配子目录,并且 RewriteRule ^/puzzle/[^/]*
不是一个选项,该检查被推迟到 RewriteCond
使用(转义的)%{REQUEST_URI}
。
关于php - utf-8 字符和 apache2 重写规则的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2916194/