我正在将我的网站转换为ssl
。我的 htaccess 目前有现有规则,我想添加一条规则来重写所有http
请求https
(它是一个共享服务器,我无法访问配置文件,所以这是唯一的方法)。
所讨论的主要两个规则是第一条(http
到https
)和最后一条(删除www
)。
我想弄清楚的是,在这种情况下,链接规则会发生什么,以及我是否需要[L]
带有重命名规则的指令http
。https
我知道[L]
指令会导致.htaccess
循环,如果可能的话,只通过一次规则会更有效。如果不使用指令[L]
(带有http
重https
命名规则),www
重命名规则是否仍可以在一次通过中起作用?
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}[L,R=301]
#Rules for Versioned Static Files - remove timestamp
RewriteRule ^(js|js-common|css|css-common|img|img-common)/(.+)\.([0-9])+\.(js|css|php|jpg|gif|png)(.*)$ $1/$2.$4$5 [L]
#rename invalid file and directory requests
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?redirectroot=%{REQUEST_URI}
#direct favicon requests to img directory
RewriteCond %{REQUEST_URI} !^/img/favicon.ico [NC]
RewriteCond %{REQUEST_URI} favicon\.ico [NC]
RewriteRule (.*) https://example.com/img/favicon.ico [R=301]
# remove www.
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]
答案1
是的,L
(last
)标志对于这些是必需的外部(规范)重定向。“链式”实际上并不适用 - 这些是外部重定向- 您希望尽快停止处理并将重定向响应发送回客户端。如果您未包含该L
标志,则处理将继续通过文件并重写到您的前端控制器前发生重定向 - 这肯定是你不希望发生的(因为它可能会导致外部重定向到/index.php?redirectroot=....
)。
事实上,你的指令顺序不对。一般来说,外部重定向应该永远来前 内部重写。您的规范重定向(www 和 HTTPS)应该放在一起,靠近文件的顶部,而不是末尾。
此外,您的 www 到非 www 重定向会重定向到http://
,这与您的 HTTP 到 HTTPS 重定向直接冲突,从而造成不必要的循环。
您的 HTTP 到 HTTPS 重定向也无效,因为标志前缺少一个空格RewriteRule
。
总结一下:
RewriteEngine On
# remove www.
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#direct favicon requests to img directory
RewriteCond %{REQUEST_URI} !^/img/favicon.ico
RewriteRule favicon\.ico /img/favicon.ico [NC,L]
#Rules for Versioned Static Files - remove timestamp
RewriteRule ^(js|js-common|css|css-common|img|img-common)/(.+)\.([0-9])+\.(js|css|php|jpg|gif|png)(.*)$ $1/$2.$4$5 [L]
#rename invalid file and directory requests
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?redirectroot=%{REQUEST_URI}
通过在 HTTPS 重定向之前将 www 重定向到非 www 重定向并重定向到规范https://
,您可以避免两次潜在的重定向。
该QSA
标志不是必需的,除非您明确地在其中包含查询字符串代换并且您希望将其与请求中的查询字符串合并。(您未在 www 到非 www 重定向中包含查询字符串,因此不需要此标志。)
我改变了你的重定向到到/img/favicon.ico
到内部重写。不知道你为什么要这么做重定向这里?我还想质疑这里标志的用途NC
。只有在特别需要时,您才应该使匹配不区分大小写。
此外,我NC
已从否定 RewriteCond
指令。思考一下其中的逻辑。
我知道
[L]
指令会导致.htaccess
循环
在.htaccess
(目录)上下文中,该L
标志终止当前文件传递.htaccess
。但是,处理确实会“循环”,直到请求通过而不发生任何变化 - 除非是外部重定向 ( R=3xx
),这会立即触发。