我经历了在这里find的问题/解决scheme,尝试了很多方法(包括[L]指令),但没有什么真正的诀窍。
情况概览
Debian通过nginx运行Apache 2.2代理
目标
将所有内容redirect到/index.php
并确保总是有一个斜杠。
从规则中排除以下目录:
排除规则中的所有.css文件。
问题
当我打电话给www.url.com/js_static
时,Apache / nginx会导致301
redirect循环。 (问题也出现在跟踪斜线 – 没有区别)
当前的解决scheme
nginx是这样configuration的:
gzip_proxied any; rewrite ^/(.*)/$ /$1; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:AES256+EDH';
Apache是这样configuration的:
RewriteEngine On RewriteCond %{SCRIPT_FILENAME} !^.+\.(css) RewriteCond %{REQUEST_URI} !^.+js_static RewriteCond %{REQUEST_URI} !^.+media RewriteRule ^(.*)$ /index.php/$1 AllowEncodedSlashes On
我没有看到问题出在哪里。 我有一个理论是nginx / apache重写的组合会产生问题,所以我摆弄的configuration,但无济于事,不幸的是。
有人可以在这里找出问题吗?
tl; dr “问题”很可能是由mod_dir(Apache)在请求一个物理目录时自动附加斜杠导致的。 但是,禁用mod_dir(即DirectorySlash Off
)不一定是答案。
跟踪斜线也会出现问题 – 没有任何区别
在您的Nginxconfiguration(您的前端代理)中,您无条件地通过内部重写从所有URL(包括目录)中删除尾部的斜线。 所以,不pipe你是否在最初的请求中包含了尾部的斜线,它确实没有什么区别。
Apache mod_dir(默认情况下)将通过外部301redirect请求一个物理目录(还没有结尾的斜杠)时自动附加一个斜线。 它这样做是为了“修复”URL。 “一个目录”并不是一个有效的资源(你希望返回什么?)。 一旦“固定”,mod_dir就会尝试返回该目录中的目录索引文件(例如index.html
):
example.com/directory
301redirect到example.com/directory/
example.com/directory/
内部重写为example.com/directory/index.html
(或任何DirectoryIndex
文档被发现)。 或者,如果没有目录索引,则为403 Forbidden(除非自动目录索引已启用 – 不推荐)。 但是,在redirect到example.com/directory/
,请求会再次触发您的Nginx代理,从而剥去尾部的斜线….等等。301redirect循环。
我个人的偏好是始终在物理目录上留下斜线。 但是,如果您想要从所有URL中删除尾部斜杠,则需要禁用mod_dir的自动行为,并通过内部重写手动附加后面的斜杠(因为在此情况下请求没有尾部斜杠的裸露目录不是严格有效的)。
尝试将您的Apacheconfiguration更改为以下内容
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]
我认为这是在你的服务器configuration(而不是.htaccess)? 但是,以前的RewriteRule
在服务器configuration中使用时会导致replace中的双斜杠。 这应该仍然正确解决,但是,它可能会打破一些东西。
我也使这更“通用”。 不是专门检查包含js_static
或media
.css
文件和URL, js_static
简单地检查以确保请求不是用于物理文件。 作为一个“前端控制器”,这是比较常见(也是灵活的)。 但是,如果您特别需要,可以将其更改回来(但是如果您有这些问题,可能会有潜在的问题)。
当我打电话给
www.example.com/js_static
时,redirect循环
另外:我不希望这是一个有效的要求吗?
只是为了在评论中回应TeroKilkanen的担忧。 不build议使用Nginx和Apache进行相关的重写。