我研究了这里找到的问题/解决方案,尝试了多种方法(包括 [L] 指令),但没有一个真正起作用。
情况概述
Debian 通过 nginx 运行 Apache 2.2 代理
目标
将所有内容重定向到/index.php
并确保始终带有斜杠。
从规则中排除以下目录:
- js_static
- 媒体
从规则中排除所有.css 文件。
问题
301
当我调用时,Apache/nginx 会导致重定向循环www.url.com/js_static
。(问题也发生在尾部斜杠上——没有区别)
当前的解决方案
nginx配置如下:
gzip_proxied any;
rewrite ^/(.*)/$ /$1;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:AES256+EDH';
Apache 配置如下:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !^.+\.(css)
RewriteCond %{REQUEST_URI} !^.+js_static
RewriteCond %{REQUEST_URI} !^.+media
RewriteRule ^(.*)$ /index.php/$1
AllowEncodedSlashes On
我看不出问题出在哪里。我当时的理论是,nginx/apache 重写的组合会产生问题,所以我摆弄了一下配置,但不幸的是,无济于事。
有人能在这里指出这个问题吗?
答案1
总结“问题”可能是由于 mod_dir (Apache) 在请求物理目录时自动添加斜线而引起的。但是,禁用 mod_dir (即DirectorySlash Off
) 不一定是答案。
问题也出现在尾部斜杠上——没有区别
在你的 Nginx 配置(你的前端代理)中,你无条件地通过内部重写删除所有 URL(包括目录)的尾部斜杠。因此,无论您是否在初始请求中包含尾部斜杠,实际上都没有区别。
Apache mod_dir(默认情况下)在通过外部 301 重定向请求物理目录(尚未带有尾部斜杠)时会自动附加斜杠。这样做是为了“修复”URL。“目录”严格来说不是有效资源(您希望返回什么?)。“修复”后,mod_dir 会尝试返回index.html
该目录中的目录索引文档(例如):
example.com/directory
301 重定向至example.com/directory/
example.com/directory/
内部重写example.com/directory/index.html
(或DirectoryIndex
找到的任何文档)。或者,如果没有目录索引,则会出现 403 Forbidden(除非启用了自动目录索引 - 不推荐)。
然而,重定向到之后example.com/directory/
,请求再次到达您的 Nginx 代理,它会删除尾随的斜杠......等等。301 重定向循环。
我个人的偏好是始终在物理目录上保留尾部斜杠。但是,如果您确实想从所有 URL 中删除尾部斜杠,则需要禁用 mod_dir 的自动行为并通过内部重写手动添加尾部斜杠(因为在这种情况下,请求没有尾部斜杠的裸目录并不严格有效)。
尝试将你的 Apache 配置更改为以下内容
AllowEncodedSlashes On
DirectorySlash Off
RewriteEngine On
# Internally rewrite any directories that do not have a trailing slash
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} (.*)
RewriteRule !/$ %1/ [L]
# Internally rewrite all non-static resources to index.php (with path info)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.*)$ /index.php/$1 [L]
我假设这是在你的服务器配置中(而不是 .htaccess 中)?但是,你之前的RewriteRule
配置会导致代换在服务器配置中使用时。这应该仍能正确解决,但是,它可能会破坏某些东西。
我还将其变得更“通用”。它不会专门检查.css
包含 或 的文件和 URL ,js_static
而是media
仅检查请求是否针对物理文件。作为“前端控制器”,这更为常见(且灵活)。但是,如果您有特殊需要,可以将其改回(但这样做可能会出现问题)。
...当我调用时重定向循环
www.example.com/js_static
在旁边:无论如何,我不认为这是一个有效的请求?
只是为了回应评论中 TeroKilkanen 的担忧。不建议同时使用 Nginx 和 Apache 进行相关重写。