我的 .htaccess 文件遇到问题。
该文件更改了丑陋的 URL,例如 http://localhost/news.php?article_slug=example-1
至http://localhost/news/example-1
这工作得很好,但是当我转到 http://localhost/news
时我收到 404 错误。
在 news.php 中我有一个重定向;因此,如果 URL 中没有文章 slug,它将重定向到latest.php。
我在 news.php 上的 PHP 代码
$article_slug=$_GET['article_slug'];
if (empty($_GET)) {
header("Location: ../latest.php");
die();// no data passed by get
}
这是我目前在 .htaccsess 文件中的内容
Options -MultiViews
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteRule ^news/([\w\d-]+)$ /news.php?article_slug=$1[QSA,L]
RewriteCond %{QUERY_STRING} article_slug=([\w\d-]+)
RewriteRule ^news$ /news/%1 [R,L]
RewriteRule ^category/([\w-]+)$ /category.php?category_slug=$1&page=$2 [QSA]
当我尝试自己调试这个(知识很少)并添加以下行时,它会重定向到latest.php
RewriteRule ^([^/]*)/?$ /news.php [L,QSA]
但是在重定向的页面上我收到以下错误
The page isn’t redirecting properly
Firefox has detected that the server is redirecting the request for this
address in a way that will never complete.
This problem can sometimes be caused by disabling or refusing to accept cookies
当我在 Firefox 中使用开发者工具时,正如 IMSoP 所评论的那样,我看到的只是latest.php 重新加载了多次。
这不仅与latest.php 隔离,还与访问文件中未列出的服务器上的任何文件隔离
当我删除线
RewriteRule ^([^/]*)/?$ /news.php [L,QSA]
我可以加载 PHP 文件,但它不会从 news.php 和 http://localhost/news
重定向。未找到但 http://localhost/news/example-1
有效。
最佳答案
but when I go to
http://localhost/news
i get a 404 error.
您的规则都没有捕获此类请求,因此不会发生重写,并且您会收到 404。
RewriteRule ^([^/]*)/?$ /news.php [L,QSA]
这会将所有内容重写为 /news.php
,包括/latest.php
您在 PHP 脚本中重定向到的目录,并且循环重复,导致重定向循环到 /latest.php
.
但是,PHP 代码中的此重定向似乎也假设原始请求上有斜杠。 IE。应该是/news/
(带有尾部斜杠)不是 /news
(没有尾部斜杠)正如您在问题中所述。
最好在 PHP 脚本中重定向到相对根目录(或绝对 URL)。 IE。 header('Location: /latest.php');
RewriteRule ^news/([\w\d-]+)$ /news.php?article_slug=$1[QSA,L] RewriteCond %{QUERY_STRING} article_slug=([\w\d-]+) RewriteRule ^news$ /news/%1 [R,L]
(请注意,您在第一条规则中的“flags”参数之前缺少一个空格。)
可以修改第一条规则以允许 news/
不仅仅是news/<something>
。这是通过简单地更改量词 +
来实现的。 (1 个或多个)至 *
(0 或更多)在捕获子模式上。
第二条规则当前没有执行任何操作。您可能应该定位 news.php
这里。但规则的顺序也是错误的。
如 my answer 中所述对于您之前的问题,\d
速记字符类不是必需的,因为 \w
(单词字符)已经包含数字。
请尝试以下操作:
RewriteCond %{QUERY_STRING} (?:^|&)article_slug=([\w-]*)(?:$|&)
RewriteRule ^news\.php$ /news/%1 [R=301,L]
RewriteRule ^news/([\w-]*)$ /news.php?article_slug=$1 [QSA,L]
请注意,第一条规则应该是 301(永久)重定向,而不是 302(最初)。但始终首先使用 302 进行测试,以避免潜在的缓存问题。
这允许请求 /news/
,但不是/news
(没有尾部斜杠)。其中只有一项可以是规范的。如果您需要办理/news
那么您还应该重定向以附加尾部斜杠(因此 /news/
是规范的,并且您应该始终链接到的 URL。)例如,在上述两条规则之前:
# Append trailing slash if omitted (canonical redirect)
RewriteRule ^news$ /$0/ [R=301,L]
摘要
综合以上几点:
Options -MultiViews
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
# Append trailing slash if omitted (canonical redirect)
RewriteRule ^news$ /$0/ [R=301,L]
RewriteCond %{QUERY_STRING} (?:^|&)article_slug=([\w-]*)(?:$|&)
RewriteRule ^news\.php$ /news/%1 [R=301,L]
RewriteRule ^news/([\w-]*)$ /news.php?article_slug=$1 [QSA,L]
RewriteRule ^category/([\w-]+)$ /category.php?category_slug=$1 [QSA,L]
但是,现在这同样适用于您的 /category
网址。这也在您的 earlier question 中进行了讨论。 。 (我删除了多余的 &page=$2
部分并添加了缺失的 L
标志。)
如果您有许多遵循类似模式的此类 URL(例如 news
和 category
等),则不一定需要为每个 URL 制定单独的规则。 (供读者练习。)
更新:
$article_slug=$_GET['article_slug']; if (empty($_GET)) { header("Location: ../latest.php"); die();// no data passed by get }
正如评论中所讨论的,这应该是:
$article_slug = $_GET['article_slug'] ?? null;
if (empty($article_slug)) {
header("Location: /latest.php");
die(); // no data passed by get
}
关于php - htaccess无限循环问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75419275/