我知道典型问题并已阅读,但我似乎无法在那里找到一些东西。
以下是我放弃www
和强制的条件和规则https
:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L,NE]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
我明白我想匹配什么。但是替换规则对我来说有点不清楚。我不明白的是:
- 我的主机名(不带 )为什么
www.
变成%1
? - 为什么应用第二条规则时查询字符串不会丢失?
第二个问题背后的原因是手动的明确指出(我突出显示):
请求 URI
请求的 URI 的路径部分,例如“/index.html”。这特别排除了查询字符串它可以作为其自己的变量使用,名为 QUERY_STRING。
答案1
我认为这些指令运行正常,您只是想解释一下为什么?
- 我的主机名(不带 )为什么
www.
变成%1
?
%1
是反向引用到最后匹配的第一个捕获组条件模式。因此,给定以下条件:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
正则表达式(即。条件模式)^www\.(.*)$
与服务器变量进行匹配。当满足正则表达式时,HTTP_HOST
匹配成功,后跟HTTP_HOST
^www\.(.*)$
www.
任何事物。 那任何事物是捕获组(带括号的子模式)的一部分。即,(.*)
而不仅仅是.*
。与(.*)
组匹配的任何内容都保存在%1
反向引用中,稍后可以在RewriteRule
代换。例如,给定 的请求www.example.com/something
,它将变为:
RewriteCond www.example.com ^www\.(.*)$ [NC]
%1
因此将包含example.com
。
为什么应用第二条规则时查询字符串不会丢失?
因为,如果你没有在RewriteRule
代换那么请求中的查询字符串是自动地附加到结果的末尾代换。
但是,如果你在代换,即使只是一个空查询字符串(?
后面没有任何内容),也不会附加来自请求的查询字符串。例如:
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI}? [R=301,L,NE]
这将导致查询字符串从请求中删除(请注意结尾的?
)。或者,在 Apache 2.4+ 上,您可以使用QSD
(查询字符串丢弃)标志来防止附加查询字符串。
在旁边:我还删除了RewriteRule
图案。这里不需要捕获组,因为您使用的是REQUEST_URI
服务器变量。(这将在反向引用中可用$1
- 请注意$
前缀。在不需要反向引用时存储它们只是浪费资源并妨碍可读性。)
RewriteCond %{HTTP:X-Forwarded-Proto} !https
我假设您的服务器位于设置标头的代理服务器后面X-Forwarded-Proto
?