Apache 为什么.htaccess重写代码不是';不能正确重定向吗?
它陷入了无尽的重定向循环。如果在上一个重写规则中,我使用END而不是L,它将按预期工作。为什么它会这样做?有没有其他方法来解决它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
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将在应用每个规则之前记录它。