如何解决.htaccess的多个重写规则,同时包含index.php
具体地说,我想将所有非www页面重定向到www,同时还要运行位于我的根目录中的index.php文件。为了解决这两个问题,我使用了.htaccess
。
我已经设置了站点来运行PHP文件以在每个目录中运行。但是,当我添加从非www到www的重定向时,它就中断了。
问题似乎在于,多个重写规则相互冲突。一个运行,而另一个则不运行,或者站点仅响应500错误。
我的问题是,是否应将多个重写规则“组合”为一个?还是我只是使用这些多个规则错误? (或者只是我弄乱了一些奇怪的语法?我已经花了一段时间了哈哈)
非常感谢您的帮助。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,QSA]
# Redirect to www.
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
</IfModule>
解决方法
我发现这可行:
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] #if not already index.php RewriteCond %{REQUEST_FILENAME} !-f #only if NOT a FILE (directory / non-existent file) RewriteRule . /index.php [L] #redirect to index.php RewriteCond %{HTTP_HOST} ^example.com$ RewriteRule ^(.*) https://www.example.com/%{REQUEST_FILENAME} [R=301,L] #redirect to https://www </IfModule>
由于存在许多错误,因此这可能无法“正常工作”:
-
您缺少开头
<IfModule mod_rewrite.c>
指令。但是,无论如何都不需要此<IfModule>
包装器,应该将其删除。 -
Apache不支持行尾注释。具体来说,由于“错误的标志定界符”,以下行将导致500错误:
RewriteCond %{REQUEST_FILENAME} !-f #only if NOT a FILE (directory / non-existent file)
(更新:如果在这里没有看到500错误响应,则可能是您在LiteSpeed服务器上;而不是Apache?在LiteSpeed上,此行尾注释似乎可以正常工作! )
-
重定向到
www
的外部重定向(最后)永远不会处理目录请求(包括根目录)或实际文件(index.php
除外)以外的任何事情。该重定向需要先进行,在现有重写之前。但是,请参阅下一点... -
您在目标URL中错误地使用了
REQUEST_FILENAME
(绝对文件系统路径)-这将导致格式错误的重定向。您可以改用REQUEST_URI
服务器变量(完整的URL路径),但是请注意,您还存在双斜杠问题。因此,它需要像下面这样重写:RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
次要点:
-
RewriteBase
不在此处使用,可以安全地删除。 (除非您还有其他使用此指令的指令?)
摘要
将以上几点结合在一起,我们就有:
RewriteEngine On
# Redirect to https://www
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Stop here if already index.php
RewriteRule ^index\.php$ - [L]
# Only if NOT a FILE (non-existent file)
RewriteCond %{REQUEST_FILENAME} !-f
# Rewrite to index.php (in the document root)
RewriteRule . /index.php [L]
请注意,这仍然会将目录重写为/index.php
,这与您的注释所说的相反。
首先使用302(临时)重定向进行测试,以避免潜在的缓存问题。
在测试之前,您需要清除浏览器缓存。
,经过大量的修补/研究,我发现这可行:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L] #if not already index.php
RewriteCond %{REQUEST_FILENAME} !-f #only if NOT a FILE (directory / non-existent file)
RewriteRule . /index.php [L] #redirect to index.php
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*) https://www.example.com/%{REQUEST_FILENAME} [R=301,L] #redirect to https://www
</IfModule>
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>