为什么 RewriteCond %{REQUEST_URI} 会干扰第二个 NOT 条件?

为什么 RewriteCond %{REQUEST_URI} 会干扰第二个 NOT 条件?

首先有效的规则是:

DirectoryIndex index.php
ErrorDocument 403 /form.html

RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule . - [F,L]

这意味着http://example.com并且http://example.com/index.php只能通过 打开POST

现在的问题是

我添加了以下附加规则集:

RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

现在,我再次发送 POSThttp://example.com但收到此错误:

Forbidden

You don't have permission to access / on this server.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

这没有意义,因为规则不应该在index.php发送 403 时捕获请求,但是好吧,我扩展了第二条规则如下:

RewriteCond %{REQUEST_URI} !^/form\.html$
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

并再次发送 POST 至http://example.com没有返回 500,但我仍然收到 403?!

更新 1
如果我删除第一个规则集,第二个规则集将按预期单独运行。这意味着只有http://example.comhttp://example.com/index.phphttp://example.com/form.html可以访问。

更新 2
如果我使用这两组规则并发送我的 POST 至,http://example.com/index.php我不会收到任何错误?!

因此,仅当我向根 URL 发送 POST 时,规则才会干扰。但为什么呢?

答案1

RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule . - [F,L]

假设您的DirectoryIndex设置为index.php并且您没有其他指令,那么似乎是您的第一个规则块导致访问 时出现 403 Forbidden http://example.com/。以上仅允许直接对 发出 POST 请求/index.php

RewriteRule 图案(单个点)在上述中完全阻止了对 的请求的规则处理http://example.com/。然后,mod_dir 启动对 的内部子请求/index.php。请注意,此子请求实际上显示为内部 GET 请求(REQUEST_METHOD服务器变量设置为该请求),因此上述条件(!POST)成功,请求最终被禁止。

最好将请求规范化,并将任何 请求从外部重定向(308 - 永久重定向,保留请求方法)到/index.php/然后,您可以集中精力匹配/,而忽略子请求。

# Exception for error document (before other directives)
RewriteRule ^form\.html$ - [L]

# Canonicalise URL and remove "index.php" if requested
RewriteRule %{REDIRECT_STATUS} ^$
RewriteRule ^index\.php$ / [R=308,L]

# Only allow POST requests to the document root
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule ^$ - [F]

(使用L时不需要标志。是隐含的。)FL

测试前请确保浏览器缓存已清除。(最好使用R=307(临时)重定向进行测试以避免缓存。)

RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

正如您所建议的,这并不与上述规则冲突,它匹配除/and之外的任何内容/index.php(在 中使用时.htaccess)。因此,这将禁止访问所有其他 URL,无论请求方法如何。(如上所述,它似乎是访问 时触发 403 的第一条规则http://example.com/。)只要您为错误文档包含例外情况(如上所述),那么您无需添加其他条件。

相关内容