繁体   English   中英

如何停止RewriteEngine / PHP重定向循环?

[英]How to stop RewriteEngine/PHP redirect loop?

任务看起来很简单:

所有请求必须通过一个文件传递。

然而,

当以下代码添加到httpd.conf时:

RewriteEngine On  
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?route=$1 [QSA,R=301,L]

并将以下代码添加到/index.php:

if( isset($_GET["route"]) && $_GET["route"] != "/index.php" ){
header("Location: ".$_GET["route"]);
}

然后它会导致重定向循环!

例如这样的循环的原因:

www.site.com/image.jpg - >(由httpd.conf重定向)

www.site.com/index.php?route=/image.jpg - >(由index.php重定向)

www.site.com/image.jpg - >(由httpd.conf重定向)

www.site.com/index.php?route=/image.jpg - >(由index.php重定向)

...

所以,问题是:

如何阻止这个循环?

以这种方式停止:

www.site.com/image.jpg - >(由httpd.conf重定向)

www.site.com/index.php?route=/image.jpg - >(由index.php重定向)

www.site.com/image.jpg(没有进一步的重定向)

您的规则看起来不错,但R=301在您的规则中有点奇怪,因为您不希望在浏览器中公开您的内部URL。

但是,由于这种情况,PHP代码看起来很可疑:

$_GET["route"] != "/index.php" 

由于这些条件,/ /index.php本身不会通过此规则路由,因此总是true

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f

因此,您的代码将通过使用header功能连续重定向来导致重定向循环。

我建议遵守这样的规则:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /index.php?route=$1 [QSA,L]

你的PHP代码应该检查$_GET['route']存在,但是不应该做任何重定向。

这个是一个补丁,但我认为它的工作原理。

httpd.conf中:

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{QUERY_STRING} !^(.*)a=a$ [NC]
RewriteRule ^(.*) index.php?route=$1 [QSA,L]

index.php文件:

<?php
if( isset($_GET["route"]) && $_GET["route"] != "/index.php" ){
    header("Location: ".$_GET["route"].'?a=a');
}

问题是:第一次重写引擎将页面重定向到index.php 然后,在index.php ,重定向到同一个文件,但添加参数a=a 然后再次重写引擎,但是当在查询字符串中找到字符串a=a时,他没有重定向的命令,并且没有进一步的重定向。

当然这将以404错误结束,因为你只使用前两个rewritecond过滤不存在​​的文件,但我想你知道如何处理它。

首先,将它放在.htaccess文件中,而不是httpd.conf中

RewriteEngine On  
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php [QSA,R=301,L]

然后,从index.php文件中删除此重定向。 您可以通过$ _GET或$ _REQUEST获取所有变量。

多么无谓的解决方案。 当然它会导致重定向循环。 在RewriteCond-s中,您尝试捕获服务器文件系统中不存在的文件和目录名称,然后尝试将其名称传递给index.php,您可以在其中再次请求它们。

有一个样板可以派上用场,在RewriteEngine条件下它应该放在顶部:

RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} !^[\s/]*$
RewriteRule ^ - [L]

添加了一个env,它按理论工作,但我只测试了一次,看看它是否可以解决问题。

你为什么这样说:

RewriteEngine On  
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?route=$1 [QSA,R=301,L]

在httpd.conf中? 您需要将其放入名为.htaccess的文件中,将其创建到根目录中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM