php - htaccess无限循环问题

标签 php apache .htaccess mod-rewrite url-rewriting

我的 .htaccess 文件遇到问题。

该文件更改了丑陋的 URL,例如 http://localhost/news.php?article_slug=example-1http://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(例如 newscategory 等),则不一定需要为每个 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/

相关文章:

php - MYSQL ON DUPLICATE KEY UPDATE 没有更新

php - 带密码的 SHA1,不涉及密码

php - .htaccess 从站点根目录重定向到公用文件夹,在 URL 中隐藏 "public"?

Linux/Debian Apache2 mod_rewrite 内部错误

java - 设置操作系统环境变量后,Apache Maven install "' mvn' not Recognized as an internal or external command"?

apache - Laravel htaccess 问题

php - 在哪里将 PHP 实现到 HTML 和 CSS 页面中?

php - 从 php 运行可执行文件而不生成 shell

regex - htaccess 重定向到 HTTPS,除了几个 url

apache - 尝试添加强制 HTTPS 规则时的 .htaccess 重定向循环 (Amazon Elastic Beanstalk)