htaccess - 重定向到错误页面问题(带斜线或不带斜线)
htaccess - redirect to error pages issue (with slash or without slash)
重定向到错误页面时出现问题:
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 ^([^/]+)/$ .php
RewriteRule ^([^/]+)/([^/]+)/$ //.php
RewriteRule sample/(.*)/(.*)/$ /sample.php?=
ErrorDocument 400 /400.php
ErrorDocument 401 /401.php
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
ErrorDocument 410 /410.php
问题出在 RewriteRule ^([^/]+)/$ .php
的结尾斜线
如果你写 RewriteRule ^([^/]+)/?$ .php
尾斜线是可选的。
编辑
您还应该添加
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
在 RewriteRule
语句之前,由于服务器循环 - 当文件存在时,语句将通过跳过重写来中断循环。
以尾部斜杠结尾的 URL 的不同之处在于它们会无条件地重写到相应的 .php
文件中。不以尾部斜杠结尾的 URL 不会被重写 - 什么也不会发生。
当您直接请求一个不存在的 .php
文件时,无论请求是否被重写(根据您的规则),您都会看到相同的基本“找不到文件”响应。
“问题”可能是由于 PHP 在您的服务器上实施的方式所致。例如,如果所有 *.php
请求都被代理到另一个后端进程,那么这将绕过应用程序服务器上的 .htaccess
文件,您看到的“基本”404 响应可能来自代理,而不是您的应用程序服务器。
您可以通过在重写之前先检查 .php
是否存在来解决此问题(因此它不会触发 404)。如果您的 URL 中的 none 包含 .php
扩展名,您还可以将对 .php
文件的任何直接请求强制为 404(在您的服务器上,在代理请求之前 - 如果发生这种情况)。
RewriteEngine On
RewriteRule ^([^/]+)/$ .php
RewriteRule ^([^/]+)/([^/]+)/$ //.php
RewriteRule sample/(.*)/(.*)/$ /sample.php?=
前两条规则也可以合二为一。您的所有规则都缺少 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}/.php -f
RewriteRule ^([^/]+(/[^/]+)?)/$ .php [L]
# Rewrite "/sample/one/two/"
RewriteRule ^sample/([^/]+)/([^/]+)/$ sample.php?= [L]
参考:
另一个最近的问题有一个非常相似的问题并且以同样的方式解决了:
重定向到错误页面时出现问题:
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 ^([^/]+)/$ .php
RewriteRule ^([^/]+)/([^/]+)/$ //.php
RewriteRule sample/(.*)/(.*)/$ /sample.php?=
ErrorDocument 400 /400.php
ErrorDocument 401 /401.php
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
ErrorDocument 410 /410.php
问题出在 RewriteRule ^([^/]+)/$ .php
如果你写 RewriteRule ^([^/]+)/?$ .php
尾斜线是可选的。
编辑
您还应该添加
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
在 RewriteRule
语句之前,由于服务器循环 - 当文件存在时,语句将通过跳过重写来中断循环。
以尾部斜杠结尾的 URL 的不同之处在于它们会无条件地重写到相应的 .php
文件中。不以尾部斜杠结尾的 URL 不会被重写 - 什么也不会发生。
当您直接请求一个不存在的 .php
文件时,无论请求是否被重写(根据您的规则),您都会看到相同的基本“找不到文件”响应。
“问题”可能是由于 PHP 在您的服务器上实施的方式所致。例如,如果所有 *.php
请求都被代理到另一个后端进程,那么这将绕过应用程序服务器上的 .htaccess
文件,您看到的“基本”404 响应可能来自代理,而不是您的应用程序服务器。
您可以通过在重写之前先检查 .php
是否存在来解决此问题(因此它不会触发 404)。如果您的 URL 中的 none 包含 .php
扩展名,您还可以将对 .php
文件的任何直接请求强制为 404(在您的服务器上,在代理请求之前 - 如果发生这种情况)。
RewriteEngine On RewriteRule ^([^/]+)/$ .php RewriteRule ^([^/]+)/([^/]+)/$ //.php RewriteRule sample/(.*)/(.*)/$ /sample.php?=
前两条规则也可以合二为一。您的所有规则都缺少 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}/.php -f
RewriteRule ^([^/]+(/[^/]+)?)/$ .php [L]
# Rewrite "/sample/one/two/"
RewriteRule ^sample/([^/]+)/([^/]+)/$ sample.php?= [L]
参考:
另一个最近的问题有一个非常相似的问题并且以同样的方式解决了: