我在用mod_rewrite做什么?

我意识到这个规范性的问题,并已经阅读,但我似乎无法在那里find一些东西。

这里是我的条件和规则删除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] 

我明白我想要匹配什么。 但是替代规则对我来说有点不清楚。 我不明白的是:

  1. 我的主机名(没有www. )如何以%1结尾?
  2. 为什么在应用第二条规则时查询string不会丢失?

第二个问题背后的原因是手册明确指出(由我强调):

REQUEST_URI

请求的URI的path组件,例如“/index.html”。 这明显地排除了作为其自己的variablesQUERY_STRING可用的查询string

我假设这些指令工作正常,你只是在解释后为什么?

  1. 我的主机名(没有www. )如何以%1结尾?

%1是最后匹配的CondPattern中的第一个捕获组的反向引用 。 所以,给出以下条件:

 RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] 

正则expression式(即CondPattern^www\.(.*)$匹配HTTP_HOST服务器variables。 当HTTP_HOST满足正则expression式^www\.(.*)$ ,即www.时,匹配成功www. 其次是任何东西任何东西都是被捕获组的一部分(括号内的子模式)。 即。 (.*) ,而不是简单的.* 。 无论匹配什么, (.*)组都会保存在%1反向引用中,并可以在稍后的RewriteRule replace中使用 。 例如,给予www.example.com/something的请求,这变成:

 RewriteCond www.example.com ^www\.(.*)$ [NC] 

因此, %1将包含example.com

为什么在应用第二条规则时查询string不会丢失?

因为,如果您没有在RewriteRule replace中明确包含查询string,则来自请求的查询string会自动附加到结果replace的末尾。

但是,如果在replace的末尾包含一个查询string,即使只是一个空的查询string(后跟一个空格),那么请求中的查询string也不会被追加。 例如:

 RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI}? [R=301,L,NE] 

这将导致查询string从请求中被删除(注意尾部? )。 或者,在Apache 2.4 +上,您可以使用QSD (查询string放弃)标志来防止追加查询string。

另外:我也从RewriteRule 模式中删除了括号。 您不需要捕获的组,因为您正在使用REQUEST_URI服务器variables。 (这可以在$1反向引用中find – 注意$前缀。当你不需要时,存储反向引用只是浪费资源,并且妨碍可读性。)

 RewriteCond %{HTTP:X-Forwarded-Proto} !https 

我假设你的服务器在设置X-Forwarded-Proto头的代理服务器后面?