重写会导致现有目录无限循环 301 重定向

重写会导致现有目录无限循环 301 重定向

我研究了这里找到的问题/解决方案,尝试了多种方法(包括 [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该目录中的目录索引文档(例如):

  1. example.com/directory301 重定向至example.com/directory/
  2. 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 进行相关重写。

相关内容