【问题标题】:Simple .htaccess Redirect causes infinity loop简单的 .htaccess 重定向导致无限循环
【发布时间】:2019-04-01 04:09:25
【问题描述】:

有人可以帮我吗?我正在使用这个简单的语句将根 index.htm 重定向到根目录 /

Redirect 301 /index.htm /

但这会导致无限循环。它重定向到我的根目录,所以它完成了这项工作。但是现在不可能向根目录发送请求而不会收到错误消息告诉您有关无限重定向的信息。我的问题:为什么?以及如何避免这种情况?

€dit:现在我有了这个:

RewriteEngine On

RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [NC,QSA,L]

RewriteRule ^((.*)/)?index.[(php)(htm)(html)] $1
[R=301,L]

如果我注释掉其中一个规则,另一个会完美运行。但是,在每种情况下,拥有这两个规则都会导致对根的重写。请帮忙!

€dit 2:

我想要的是用一个 index.php 文件处理所有传入请求,并将每个 index.php、index.htm 和 index.html 重定向到它的目录,因为内容重复。该怎么做?

€dit 3:

现在一切都像魅力一样!

RewriteEngine On

RewriteBase /

#Redirects http://host.tld/gamedev to http://gamedev.host.tld/
Redirect 301 /gamedev/ http://gamedev.host.tld/

#Redirects every request to a subdirectory's index file to the subdirectory because of duplicated content
RedirectMatch ^/(.*)/index.(php|html?)$ http://gamedev.host.tld/$1

#Remove index file from a root folder request
RewriteCond %{THE_REQUEST} \s/index\.(php|html?)
RewriteRule ^index\.(php|html?)$ / [R=302,L]

#Handling all incoming requests with index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

非常感谢 达斯·穆恩

【问题讨论】:

  • 您的 http 服务器很可能配置为将 index.htm 文件作为目录索引提供。
  • 但是没有我的规则 index.htm 不会被重定向到根目录。否则我不需要重定向
  • 你能解释一下你想用 2 条重写规则(尤其是第 1 条)归档什么吗?也许一些例子会有所帮助。
  • 第一个应该让 index.php 文件处理每个请求
  • @DarthMoon:我认为你应该看看 DocRoot 的答案。它应该完全符合您的要求。

标签: apache .htaccess redirect url-redirection http-redirect


【解决方案1】:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [NC,QSA,L]

RewriteRule ^((.*)/)?index.[(php)(htm)(html)] $1
[R=301,L]

...拥有这两个规则会导致在每种情况下都重写根。

因为在第一条规则将请求重写为index.php 之后,重写过程重新开始,然后第二条规则从 URL 中删除 所有内容

您的第二条规则不正确。它与您认为它匹配的内容不匹配,并且不必要地与任何 URL 路径匹配。您说这只需要匹配根目录中的索引文档。

[(php)(htm)(html)] - 可能是为了匹配这些文件扩展名中的任何一个,但它匹配单个字符:phtml。要匹配phphtmhtml,您需要使用alternation。例如:(php|htm|html)(php|html?)。 (? 使l 在第二个模式中是可选的。)

这些指令的顺序也是错误的。外部重定向应该在您的前端控制器之前

@Benjamin 的答案几乎都在按钮上,除了 condition(永远不会匹配)并且它必须位于您的 .htaccess 文件的顶部。

请尝试以下方法:

RewriteEngine On

RewriteBase /

# Remove /index.php from URL
RewriteCond %{THE_REQUEST} \s/index\.php
RewriteRule ^index\.php$ / [R=302,L]

# Front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

您的重写不需要QSANC 标志。

在第一个条件中检查THE_REQUEST 的原因是为了防止重定向循环(在某些情况下)。 THE_REQUEST 包含来自初始请求的 Host 标头,并且在 URL 重写后不会更改。

使用302(临时)重定向进行测试,只有在您确定它工作正常时才将其更改为301(永久)。 301 被浏览器硬缓存,因此会使测试出现问题。与往常一样,您必须确保在测试之前清除浏览器缓存。

【讨论】:

    【解决方案2】:

    我认为你不能通过“简单重定向”来做到这一点。您获得无限循环的原因是当您访问根目录 / 时,您的 apache 正在尝试传递文件 /index.htm 的内容,因为它是目录索引列表的一部分。现在您的重定向生效(因为您虚拟访问页面/index.htm)并且程序从头开始。

    要解决您的问题,您应该使用重写规则而不是重定向。重写规则仅影响请求的 URL,不会以无限循环结束。以下规则应该适用于您的情况:

    RewriteEngine On
    RewriteCond %{THE_REQUEST} \s/index\.htm
    RewriteRule ^index.htm$ / [R=301,L]
    

    【讨论】:

    • RewriteCond 指令在此示例中永远不会匹配,因此重定向永远不会发生。 THE_REQUEST 服务器变量包含 Host HTTP 请求标头,例如。 GET /index.htm HTTP/1.1。所以你需要一个像\s/index\.htm 这样的模式。
    • 我看到了。它应该类似于 %{REQUEST_FILENAME}。但这并不能解决我的新问题。查看我的编辑。
    • @DarthMoon 不,这个 redirect 不应该是 %{REQUEST_FILENAME}?!
    • @DocRoot:感谢您的提示。如果纠正了模式。我的浏览器已经缓存了重定向,所以当我从上面测试重定向时它也可以工作。对不起。
    猜你喜欢
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 2013-06-25
    • 2021-08-14
    相关资源
    最近更新 更多