Apache %REQUEST_URI 无法正常工作

Posted

技术标签:

【中文标题】Apache %REQUEST_URI 无法正常工作【英文标题】:Apache %REQUEST_URI not working correctlyApache %REQUEST_URI 无法正常工作 【发布时间】:2017-08-15 20:02:51 【问题描述】:

虽然我设置了一些 .htaccess 文件,但我没有使用虚拟主机或任何花哨的东西。以下是我在 httpd.conf 中的重写规则:

RewriteEngine On

RewriteCond %REQUEST_URI !^/app/smsapi [NC]
RewriteRule (.*) https://www.example.com/uri=%REQUEST_URI [R,L]

这条规则基本上是说,如果 uri 以 /app/smsapi 开头,则触发重写。但是当我重新启动服务器并尝试它时,我得到了一些奇怪的结果。

当我请求 URL https://www.example.com/app/smsapi/index.php 时,我得到一个 200 成功代码,这与预期的一样。但是,当我请求 URL http://www.example.com/app/smsapi/index.php 时,它会重定向到 https://www.example.com/uri=/app/smsapi/index.php。因此,即使请求 URI 不满足条件,它实际上也会触发规则。

所以,然后我决定关闭重写规则并试一试。现在,这两个 URL 都给了我一个 200 Success 代码。

现在,我知道无法通过无法访问服务器的其他人轻松解决此问题,但我是否正确地说这是肯定 REQUEST_URI 未正确触发的问题?我已经证明,没有重写规则,一切正常,但使用重写规则,第二个 URL 被重定向。因此,重定向一定是由重写规则引起的?此外,不满足重定向规则的条件。这不就证明重写规则的功能有问题吗?

还有其他可能吗?

更新 这里发生了一些非常奇怪的事情。我设置了一个本地服务器并尝试了相同的规则,我得到的 URL http://192.168.0.112/app/ 是

http://192.168.0.112/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/uri=/app/

这是正确的,因为只要 URL 不像 /app/smsapi,它就应该重定向它。想知道为什么这在真实服务器上没有发生。此外,插入这些规则的位置似乎有所不同。 (我只是在 LoadModule 命令之后包含这些规则)。

在本地主机上,如果我将这些规则放在目录部分的上方或下方,它将不起作用。但是,如果我将它包含在 inside 目录部分,它会。

在服务器上,如果我在目录部分中包含规则,它们将不起作用。但是,如果我将它们包含在目录部分的上方或下方,它们就会开始工作。

在我看来,这似乎是由于版本不同。我的本地主机是运行 Apache 2.4.18 的 Ubuntu Desktop 16.04。而服务器是运行 Apache 2.2.15 的 CentOS 6.8。

但是,我认为为什么服务器重定向只发生一次(尽管它被配置为最多 20 次)的谜团与 https 有关。这也与即使在不匹配的规则上也重定向 https 的原始问题有关。

有人知道吗?

更新 我使用相同的规则更新了 httpd.conf 文件,但我使用了 http:// 而不是 https://,它通过 20 次重定向给了我正确的结果。这意味着我已将问题隔离到 https。

【问题讨论】:

我是否正确理解该规则会通过 http 触发,但不会通过 https 触发?如果是这样,当导航到不同的 url 时,规则是否按预期工作,例如 example.com/foo/bar ? 嗨康纳。感谢您的回复。是的,你理解正确。是的,我刚试过。无论有没有重写规则,我都可以通过 http 和 https 访问 www.example.com/git.html。所以我认为这证实了这一点。 嗨康纳。从经验来看,通常不是软件有问题,尤其是像Apache这样久经考验的软件,而是配置有问题。不要在这上面花太多时间。我会深入研究并用我发现的内容更新问题。 【参考方案1】:

您在第一句话中报告了确切的问题:“尽管我设置了一些 .htaccess 文件,但我没有使用虚拟主机或任何花哨的东西”

.htaccess 是“花哨”且过于复杂,而不是虚拟主机。

如果您首先在 virtualhost 中定义了 RewriteCond,它会起作用,但 .htaccess 是每个目录的上下文(也就是一场噩梦),并且 regex ^/ 在该上下文中永远不会匹配 .

如果您想在 per-dir 上下文(目录或 .htaccess)中匹配 REQUEST_URI,您需要删除初始斜杠,即:

RewriteCond %REQUEST_URI !^app/smsapi [NC]

另外,还请考虑您可能不需要为此添加 RewriteCond:

RewriteRule ^(?!app/smsapi)(.*) https://www.example.com/uri=$1 [R,L]

【讨论】:

你好 ezra-s。感谢您的回答。我使用过 .htaccess 但 RewriteRule 是写在 httpd.conf 文件中的。我拥有的唯一 .htaccess 文件是一个非常简单的文件。但是,我明白你的意思,我会尝试删除 .htaccess 文件,然后尝试获取 URL。 好吧@AshishK 对于循环,您可能希望使用不那么贪婪的捕获 (.*) 来重写所有内容,然后当重写着陆时,它会一次又一次地重写。 @ezra-s kudos man,由于目录上下文,我有一些简单的规则让我发疯......阅读你的答案我尝试在 VHost 中移动规则并且一切正常

以上是关于Apache %REQUEST_URI 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

使用 Apache mod_rewrite 检测空 REQUEST_URI 的问题

Apache htaccess:如果 REQUEST_URI 与 cookie 值不匹配,则拒绝

当 REQUEST_URI 与 htaccess apache2 不匹配时 RewriteCond

https不适用于apache

FROM 语句的 Apache Impala 内部查询限制

检查文件是不是来自 htaccess / Apache