简单的 .htaccess 重定向导致无限循环
Simple .htaccess Redirect causes infinity loop
有人可以帮助我吗?我正在使用这个简单的语句将根 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)]
[R=301,L]
如果我注释掉这些规则中的一个,另一个就可以完美运行。但是,同时拥有这两个规则会导致在每种情况下都对根目录进行重写。请帮忙!
€编辑 2:
我想要的是用一个 index.php 文件处理所有传入请求,并将每个 index.php、index.htm 和 index.html 重定向到它的目录,因为内容重复.怎么做?
€编辑 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/
#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]
非常感谢
达斯·穆恩
我不认为你可以用 "Simple Redirection" 来解决这个问题。您得到无限循环的原因是当您访问根目录 /
时,您的 apache 试图传递文件 /index.htm
的内容,因为它是目录索引列表的一部分。现在您的重定向生效(因为您 虚拟 访问页面 /index.htm
)并且程序从头开始。
要解决您的问题,您应该使用重写规则而不是重定向。重写规则只影响请求的 URL 并且不会以无限循环结束。以下规则适用于您的情况:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/index\.htm
RewriteRule ^index.htm$ / [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [NC,QSA,L]
RewriteRule ^((.*)/)?index.[(php)(htm)(html)]
[R=301,L]
...having both of these rules causes a rewrite to the root in every case.
因为在第一条规则将请求重写为 index.php
后,重写过程重新开始,然后第二条规则从 URL 中删除 所有内容 .
您的第二条规则不正确。它不匹配您认为匹配的内容,并且不必要地匹配任何 URL-path。你说这只需要匹配根目录下的索引文档即可。
[(php)(htm)(html)]
- 可能是为了匹配这些文件扩展名中的任何一个,但它匹配的是单个字符:p
、h
、t
、m
或 l
。要匹配 php
、htm
或 html
,您需要使用 alternation。例如:(php|htm|html)
或 (php|html?)
。 (?
使 l
在第二个模式中可选。)
这些指令的顺序也是错误的。外部重定向应该 before your front-controller.
@Benjamin 的回答几乎都在按钮上,除了 条件 (永远不会匹配)并且它必须位于 .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]
您的重写不需要 QSA
或 NC
标志。
在第一个条件中检查 THE_REQUEST
的原因是为了防止重定向循环(在某些情况下)。 THE_REQUEST
包含来自初始请求的 Host
header 并且在 URL 重写后不会更改。
使用 302
(临时)重定向进行测试,只有在您确定它工作正常时才将其更改为 301
(永久)。 301 由浏览器硬缓存,因此会使测试出现问题。一如既往,您必须确保您的浏览器缓存在测试前是清晰的。
有人可以帮助我吗?我正在使用这个简单的语句将根 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)]
[R=301,L]
如果我注释掉这些规则中的一个,另一个就可以完美运行。但是,同时拥有这两个规则会导致在每种情况下都对根目录进行重写。请帮忙!
€编辑 2:
我想要的是用一个 index.php 文件处理所有传入请求,并将每个 index.php、index.htm 和 index.html 重定向到它的目录,因为内容重复.怎么做?
€编辑 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/
#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]
非常感谢 达斯·穆恩
我不认为你可以用 "Simple Redirection" 来解决这个问题。您得到无限循环的原因是当您访问根目录 /
时,您的 apache 试图传递文件 /index.htm
的内容,因为它是目录索引列表的一部分。现在您的重定向生效(因为您 虚拟 访问页面 /index.htm
)并且程序从头开始。
要解决您的问题,您应该使用重写规则而不是重定向。重写规则只影响请求的 URL 并且不会以无限循环结束。以下规则适用于您的情况:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/index\.htm
RewriteRule ^index.htm$ / [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f RewriteRule . index.php [NC,QSA,L] RewriteRule ^((.*)/)?index.[(php)(htm)(html)] [R=301,L]
...having both of these rules causes a rewrite to the root in every case.
因为在第一条规则将请求重写为 index.php
后,重写过程重新开始,然后第二条规则从 URL 中删除 所有内容 .
您的第二条规则不正确。它不匹配您认为匹配的内容,并且不必要地匹配任何 URL-path。你说这只需要匹配根目录下的索引文档即可。
[(php)(htm)(html)]
- 可能是为了匹配这些文件扩展名中的任何一个,但它匹配的是单个字符:p
、h
、t
、m
或 l
。要匹配 php
、htm
或 html
,您需要使用 alternation。例如:(php|htm|html)
或 (php|html?)
。 (?
使 l
在第二个模式中可选。)
这些指令的顺序也是错误的。外部重定向应该 before your front-controller.
@Benjamin 的回答几乎都在按钮上,除了 条件 (永远不会匹配)并且它必须位于 .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]
您的重写不需要 QSA
或 NC
标志。
在第一个条件中检查 THE_REQUEST
的原因是为了防止重定向循环(在某些情况下)。 THE_REQUEST
包含来自初始请求的 Host
header 并且在 URL 重写后不会更改。
使用 302
(临时)重定向进行测试,只有在您确定它工作正常时才将其更改为 301
(永久)。 301 由浏览器硬缓存,因此会使测试出现问题。一如既往,您必须确保您的浏览器缓存在测试前是清晰的。