htaccess - 重定向到错误页面问题(带斜线或不带斜线)

Posted

技术标签:

【中文标题】htaccess - 重定向到错误页面问题(带斜线或不带斜线)【英文标题】:htaccess - redirect to error pages issue (with slash or without slash) 【发布时间】:2021-12-18 16:25:15 【问题描述】:

重定向到错误页面存在问题: example.com/test - 将重定向到 404 错误页面

但是 example.com/test/ - 将转到白色的“找不到文件”。页面

提及:

直到前一段时间它才正常工作(可能是 php 版本的更新??) 与 www/http/https 版本的链接行为相同 链接的标准结构是www.example.com/test/

.htaccess 文件代码

<Files .htaccess>
order allow,deny
deny from all
</Files>

RewriteEngine On
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteRule sample/(.*)/(.*)/$ /sample.php?$1=$2

ErrorDocument 400 /400.php
ErrorDocument 401 /401.php
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
ErrorDocument 410 /410.php

【问题讨论】:

那么test.php首先存在吗? 不,没有文件test.php,也没有文件夹 您检查过404.php 的内容以确保它仍然有效吗?也许将其切换到静态文件进行调试。 是的,404.php文件的内容是正确的,我宁愿坚持PHP版本。 我用静态文件进行了测试 - 结果是一样的(静态文件将在 (example.com/test) 的情况下显示,但在 (example.com/test/) 的情况下 - 会转到白色的“找不到文件。”页面 【参考方案1】:

以斜杠结尾的 URL 的不同之处在于,它们被无条件地重写为相应的 .php 文件。不以斜杠结尾的 URL 不会被重写 - 没有任何反应。

当您直接请求一个不存在的 .php 文件时,您会看到相同的基本“找不到文件”响应,无论请求是否被重写(根据您的规则)。

“问题”可能是由于 PHP 在您的服务器上实现的方式造成的。例如,如果所有*.php 请求都被代理到另一个后端进程,那么这将绕过您在应用程序服务器上的.htaccess 文件,并且您看到的“基本”404 响应可能来自代理,而不是您的应用服务器。

您可以通过在重写之前首先检查.php 是否存在来解决此问题(因此它不会触发 404)。如果您的 URLs 都不包含 .php 扩展名,您还可以强制对 .php 文件的任何直接请求为 404(在您的服务器上,在请求被代理之前 - 如果这是正在发生的事情)。

RewriteEngine On
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteRule sample/(.*)/(.*)/$ /sample.php?$1=$2

前两条规则也可以合并为一条。您在所有规则中都缺少 L 标志。您需要确保 MultiViews 被禁用,否则最后一条规则将不起作用。

此外,最后一条规则中的正则表达式需要锚定并变得更加具体,因为它匹配太多,例如。 /sample/foo/bar/baz/qux 将被重写为 /sample.php?foo/bar/baz=qux,我认为这不是本意。

请尝试以下方法:

Options -MultiViews

RewriteEngine On

# Force any direct request for ".php" files to 404
RewriteCond %ENV:REDIRECT_STATUS ^$
RewriteCond %REQUEST_FILENAME !-f
RewriteRule \.php$ - [R=404]

# Rewrite to ".php" file - 1 or 2 path segments
RewriteCond %DOCUMENT_ROOT/$1.php -f
RewriteRule ^([^/]+(/[^/]+)?)/$ $1.php [L]

# Rewrite "/sample/one/two/"
RewriteRule ^sample/([^/]+)/([^/]+)/$ sample.php?$1=$2 [L]

参考:

另一个最近的问题有一个非常相似的问题并以相同的方式解决:Custom 404 error handler in htaccess not working for non-existent ".php" files

【讨论】:

【参考方案2】:

问题在于RewriteRule ^([^/]+)/$ $1.php 的斜线结尾

如果你写RewriteRule ^([^/]+)/?$ $1.php,尾部斜杠是可选的。

编辑

你也应该添加

RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d

RewriteRule 语句之前,由于服务器循环 - 当文件存在时,语句将通过跳过重写来中断循环。

【讨论】:

通过此更改/更新,我得到“内部服务器错误” “内部服务器错误” 在您网站的 error_log 中应该有更多关于导致 500 错误的原因的信息。你能看看那里并报告它的内容吗? “问题在于斜线结尾” - 这本身不是问题。结尾的斜杠似乎出现在 OP URL 上。通过简单地使尾部斜杠可选,它将导致重写循环(内部服务器错误),因为test.php 本身将被重写为test.php.php 等(这将需要额外的文件系统检查,如在编辑)。但是使尾部斜杠 可选 是不必要的,并且可能会产生重复的内容问题(如果您愿意,请重定向以附加斜杠)。

以上是关于htaccess - 重定向到错误页面问题(带斜线或不带斜线)的主要内容,如果未能解决你的问题,请参考以下文章

htaccess mod_rewrite - 尾部斜线和重定向循环

使用 htaccess 将所有流量从根重定向到特定的子域页面

404错误页面未使用htaccess重定向到自定义页面

使用 .htaccess 文件后,从我网站上的一个页面重定向到另一个页面会导致 404 错误

页面未正确重定向 - HTTPS HTACCESS 重写错误

使用 .htaccess 将所有子域和子目录重定向到索引页面