如果目录存在,Apache mod_rewrite 将请求方法设置为 "GET"

Apache mod_rewrite sets request method to "GET" if directory exists

我目前正在使用自己编写的路由器开发 API。它使用 .htaccess 文件将所有传入请求重定向到 index.php 文件。

我发现了以下问题:如果有传入请求,例如:OPTIONS https://<domain>/auth 并且目录 auth/ 存在于根级别,则请求方法切换为 GET.

.htaccess 文件:

RewriteEngine On

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

RewriteCond %{REQUEST_FILENAME}  -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]

我该如何解决这个问题?谢谢。

这是因为 mod_dir 发出 301 重定向以将尾部斜杠附加到目录(以“修复”URL)。 301 重定向的结果是 user-agent(浏览器)将后续请求方法更改为 GET.

如果您特别希望允许这些类型的请求,那么您需要防止 mod_dir 在斜杠后附加 DirectorySlash Off。但是,您还需要确保禁用 mod_autoindex(自动生成的目录列表)(以防止意外泄露信息),如果您需要直接访问其他地方的目录,则可能会遇到问题。

例如,在您的 .htaccess 文件的顶部:

# Disable directory listings (mod_autoindex)
Options -Indexes

# Prevent mod_dir from appending the slash to directories
DirectorySlash Off

参考:


旁白:

RewriteCond %{REQUEST_FILENAME}  -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]

这些 RewriteCond 指令是多余的。您实际上是在将 所有内容 重写为 index.php。写成这样会更有效率:

RewriteRule !^index\.php$ index.php [L]