重写导致现有目录上的无限301redirect循环

我经历了在这里find的问题/解决scheme,尝试了很多方法(包括[L]指令),但没有什么真正的诀窍。

情况概览

Debian通过nginx运行Apache 2.2代理

目标

将所有内容redirect到/index.php并确保总是有一个斜杠。

从规则中排除以下目录:

  • js_static
  • 媒体

排除规则中的所有.css文件。

问题

当我打电话给www.url.com/js_static时,Apache / nginx会导致301redirect循环。 (问题也出现在跟踪斜线 – 没有区别)

当前的解决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 ):

  1. example.com/directory 301redirect到example.com/directory/
  2. 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_staticmedia .css文件和URL, js_static简单地检查以确保请求不是用于物理文件。 作为一个“前端控制器”,这是比较常见(也是灵活的)。 但是,如果您特别需要,可以将其更改回来(但是如果您有这些问题,可能会有潜在的问题)。

当我打电话给www.example.com/js_static时,redirect循环

另外:我不希望这是一个有效的要求吗?

只是为了在评论中回应TeroKilkanen的担忧。 不build议使用Nginx和Apache进行相关的重写。