我有以下情况:
网络目录中的两个前控制器(文档根目录):
web/frontend.php # handles all *.html requests
web/backend.php # direct calls only
到目前为止,重写很简单:
RewriteCond %{REQUEST_URI} !^/backend.php
RewriteRule (.+)\.html$ /frontend.php [L]
所以现在当我在后端拨打example.org/backend.php
时,没有什么特别的事情发生。当我拨打example.org/
或example.org/team/john.html
之类的内容时,会由frontend.php
处理。
到目前为止工作!
现在我希望省略* .html扩展名,以便example.org/team/john
在内部处理为example.org/team/john.html
。
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_URI}.html [L]
最后但并非最不重要的是,我希望将请求重定向到john.html
到john
,以避免重复内容。
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} ^(.+)\.html$
RewriteRule (.*)\.html$ /$1 [R=301,L]
每个部分都依赖于它自己,但我把它放在一起,我得到一个循环,这并不让我感到惊讶,但我不知道如何避免这种情况。我搜索了文档,尝试了几个标志和条件,但我完全卡住了,我需要帮助。
以下是整个.htaccess文件:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# extend html extension internally
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_URI}.html [L]
# redirect example.html to example
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} ^(.+)\.html$
RewriteRule (.*)\.html$ /$1 [R=301,L]
# frontcontroller
RewriteCond %{REQUEST_URI} !^/backend.php
RewriteRule (.+)\.html$ /frontend.php [L]
</IfModule>
任何帮助都会很棒。
答案 0 :(得分:1)
循环是因为多个内部重定向,你可以使用END标志来防止重写循环
RewriteRule ^(.+)\.html$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_URI}.html [END]
答案 1 :(得分:1)
为避免循环,您可以使用THE_REQUEST
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} "\.html "
RewriteRule ^(.*)\.html$ /$1 [R,L]
无关,但您可以简化规则。第一个
RewriteCond %{REQUEST_URI} !^/backend.php
RewriteRule (.+)\.html$ /frontend.php [L]
您已检查(.+)\.html
,因此可以省略RewriteCond
。接下来,您不会使用捕获的部分(.+)
。将其替换为.
以确保其不为空。这给出了
RewriteRule .\.html$ /frontend.php [L]
第二个,除非您的网站中有*.html.html
个文件,否则您无需检查!html
,只需使用^
RewriteRule
即可模式
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [L]