Apache 编码 URI 导致 404

Apache 编码 URI 导致 404

我遇到了一个奇怪的问题。我使用的框架在 mod_rewrite 重写 URL 后被调用。如果 URI 中的字符带有重音符号(如拉丁字母),则请求永远不会发送到我的框架,而服务器会出错并显示 404。我使用的是 Windows 计算机,因此不确定这是否与此有关。只要 URI 中没有重音符号,请求就会毫无问题地发送到框架。有人能告诉我这是怎么回事以及如何解决这个问题吗?

编辑:以下是我的 access.log 中的两行。第一行显示 404,其中重音符号Å由 Apache 编码,但未传递。当我将ÅURI 中的 更改为英文“A”时,一切都按预期运行。

127.0.0.1 - - [20/Oct/2017:13:50:50 -0400] "GET /actor/%C3%85ker HTTP/1.1" 404 222
127.0.0.1 - - [20/Oct/2017:13:54:48 -0400] "GET /actor/Aker HTTP/1.1" 200 5701

编辑:.htaccess这些是文件 中的行

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?request=$1 [L,QSA]

这是由两个人组成的调试日志的一部分,其中显示对于其中一个人,mod_rewrite 没有将请求转发到我的框架,而另一个人却转发了。

这是失败的:

[Fri Oct 20 17:52:48.119655 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52846] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1fec230/initial] [perdir C:/Development/Apache24/htdocs/ansac/] add path info postfix: C:/Development/Apache24/htdocs/ansac/actor -> C:/Development/Apache24/htdocs/ansac/actor/\xc3\x85kerman, referer: http://ansac.com/
[Fri Oct 20 17:52:48.119655 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52846] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1fec230/initial] [perdir C:/Development/Apache24/htdocs/ansac/] strip per-dir prefix: C:/Development/Apache24/htdocs/ansac/actor/\xc3\x85kerman -> actor/\xc3\x85kerman, referer: http://ansac.com/
[Fri Oct 20 17:52:48.119655 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52846] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1fec230/initial] [perdir C:/Development/Apache24/htdocs/ansac/] applying pattern '^(.*)$' to uri 'actor/\xc3\x85kerman', referer: http://ansac.com/
[Fri Oct 20 17:52:48.119655 2017] [rewrite:trace1] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52846] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1fec230/initial] [perdir C:/Development/Apache24/htdocs/ansac/] pass through C:/Development/Apache24/htdocs/ansac/actor, referer: http://ansac.com/

奇怪的是,这个有效:

[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] add path info postfix: C:/Development/Apache24/htdocs/ansac/actor -> C:/Development/Apache24/htdocs/ansac/actor/Gonz\xc3\xa1lez
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] strip per-dir prefix: C:/Development/Apache24/htdocs/ansac/actor/Gonz\xc3\xa1lez -> actor/Gonz\xc3\xa1lez
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] applying pattern '^(.*)$' to uri 'actor/Gonz\xc3\xa1lez'
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace4] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] RewriteCond: input='C:/Development/Apache24/htdocs/ansac/actor' pattern='!-f' => matched
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace4] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] RewriteCond: input='C:/Development/Apache24/htdocs/ansac/actor' pattern='!-d' => matched
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace2] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] rewrite 'actor/Gonz\xc3\xa1lez' -> 'index.php?do=actor/Gonz\xc3\xa1lez'
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] split uri=index.php?do=actor/Gonz\xc3\xa1lez -> uri=index.php, args=do=actor/Gonz\xc3\xa1lez
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] add per-dir prefix: index.php -> C:/Development/Apache24/htdocs/ansac/index.php
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace2] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] strip document_root prefix: C:/Development/Apache24/htdocs/ansac/index.php -> /index.php
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace1] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ff8290/initial] [perdir C:/Development/Apache24/htdocs/ansac/] internal redirect with /index.php [INTERNAL REDIRECT]
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ffd7c0/initial/redir#1] [perdir C:/Development/Apache24/htdocs/ansac/] strip per-dir prefix: C:/Development/Apache24/htdocs/ansac/index.php -> index.php
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace3] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ffd7c0/initial/redir#1] [perdir C:/Development/Apache24/htdocs/ansac/] applying pattern '^(.*)$' to uri 'index.php'
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace4] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ffd7c0/initial/redir#1] [perdir C:/Development/Apache24/htdocs/ansac/] RewriteCond: input='C:/Development/Apache24/htdocs/ansac/index.php' pattern='!-f' => not-matched
[Fri Oct 20 17:56:42.415807 2017] [rewrite:trace1] [pid 1620:tid 792] mod_rewrite.c(480): [client 127.0.0.1:52856] 127.0.0.1 - - [ansac.com/sid#2de668][rid#1ffd7c0/initial/redir#1] [perdir C:/Development/Apache24/htdocs/ansac/] pass through C:/Development/Apache24/htdocs/ansac/index.php

为什么其中一个有效而另一个无效?两个名字中都有重音符号,但其中一个失败了。

答案1

一个假设……

RewriteRule .* index.php?request=$1 [L,QSA]

这行看起来就像一个错误,因为$1反向引用将总是为空,因为没有捕获组RewriteRule 图案

“框架”可能仍然有效(对于拉丁字母),因为它可能正在解析$_SERVER['REQUEST_URI']PHP 超全局变量(可能作为后备)——许多框架都是这样做的。但是,$_SERVER['REQUEST_URI']将保持 URL 编码(例如/actor/%C3%85ker)——因此,在通过框架路由之前,可能需要对其进行 URL 解码(例如/actor/Åker)。这可能是问题所在。另一方面,像这样的请求/actor/Aker无论是否经过 URL 编码都是相同的,因此这不会影响这样的 URL。

但是,如果您的框架允许使用 URL 参数覆盖请求的 URL,request那么请考虑将上述指令更改为:

 RewriteRule (.*) index.php?request=$1 [L,QSA]

即附上RewriteRule 图案在括号内。

这将导致捕获的 URL 路径在requestURL 参数中传递。现在,与此的重要区别在于,指令RewriteRule匹配的 URL 路径已经经过 URL 解码。因此,requestURL 参数已经包含 URL 解码的请求(尽管少了斜杠前缀),例如actor/Åker。。


更新:尝试改变RewriteRule 图案改为从.*[\s\S]*。例如:

 RewriteRule ([\s\S]*) index.php?request=$1 [QSA,L]

这只是一个稍微更全面的模式。虽然.(点)匹配任何字符(不包括换行符),但[\s\S]匹配任何空格和非空格字符(即。一切)。

答案2

  1. 查看日志。Apache 错误日志中显示其正在查找的文件的路径是什么?该文件的路径是否存在?

  2. 这听起来像是字符编码问题。确保在 Apache 中正确配置了字符编码。不幸的是,我对此没有具体的建议。

相关内容