Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache 为什么.htaccess重写代码不是';不能正确重定向吗?_Apache_.htaccess_Redirect_Mod Rewrite_Web Development Server - Fatal编程技术网

Apache 为什么.htaccess重写代码不是';不能正确重定向吗?

Apache 为什么.htaccess重写代码不是';不能正确重定向吗?,apache,.htaccess,redirect,mod-rewrite,web-development-server,Apache,.htaccess,Redirect,Mod Rewrite,Web Development Server,它陷入了无尽的重定向循环。如果在上一个重写规则中,我使用END而不是L,它将按预期工作。为什么它会这样做?有没有其他方法来解决它 RewriteEngine on #remove tailing slashes RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/+$ /$1 [R,L] #external redirect: /page.php to /page RewriteCond %{REQUEST_FILENAME} !-d

它陷入了无尽的重定向循环。如果在上一个重写规则中,我使用END而不是L,它将按预期工作。为什么它会这样做?有没有其他方法来解决它

RewriteEngine on

#remove tailing slashes
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/+$ /$1 [R,L]

#external redirect: /page.php to /page
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)\.php$ /$1 [R,L]

#internal redirect: page to page.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*?)$ $1\.php [L]
我的Apache版本是2.4.43


解决方案:

我想我现在明白到底发生了什么。Mod_rewrite只在URI的一个版本上工作,当我使用R标志时,更改只在浏览器中可见。再加上@anubhava的答案,就是导致无休止的重定向循环的原因。换句话说,我认为
RewriteRule^(.*)\.php$/$1[R,L]
RewriteRule^(.*)$$1\.php[L]
在同一版本的URI上实际上不起作用

R旗说明:
标志
L
END
的行为不同
L
标志意味着再次运行重写循环(在while循环中类似于
continue
),并且
END
循环终止循环(在while循环中类似于
break

END
标志是在Apache2.4中引入的,它用于防止您当前观察到的重写循环

当您使用
L
时,最后一条规则将在请求uri末尾添加
.php
,当重写循环再次运行时,外部重定向将从请求uri中删除
.php
,然后最后一条规则再次在请求uri末尾添加
.php
。此循环将继续并导致无限循环。为了防止这种情况发生,您可以在上一条规则中使用
END
标志,该标志仅终止当前请求的mod_rewrite执行,并防止循环行为


您的上一条规则
重写规则^(.*?$$1\.php[L]
将把任何url重定向到该url+
.php
。因此,您将得到如下URL:
index.php.php.php.php.php.php.php.php.php.php.php
,URL将继续无限地重写自身。
[L]
标志并不意味着这应该是执行的最后一条规则。这意味着这是在返回开始并重新开始之前要执行的最后一条规则。您的Apache版本是什么?是否
RewriteCond%{REQUEST_FILENAME}\.php-f
help?Apache 2.4.43-1但我的最后一条规则只服务于.php文件?它不会更改请求URI,还是会?我的每个重写块本身都可以正常工作,但第二个和第三个块的组合会产生错误。我知道mod_重写引擎在.htaccess文件中循环运行,我知道END和L标志的作用。它确实会更改请求URI。当我只测试最后一个代码块时,如果浏览器中的地址栏保持不变,它如何更改URI?我认为更改URI会导致用户地址栏的更改,或者这是R(edirect)标志所做的吗?@HerculePoirot:Request URI在浏览器中不会更改,因为上一条规则中没有外部重定向,但在内部它会在
mod_rewrite
执行中更改。如果启用
RewriteLog
,则Apache将在应用每个规则之前记录它。