Apache 将除一个子域之外的任何子域重写为非 www https

Apache 将除一个子域之外的任何子域重写为非 www https

我正在尝试减少服务器上的 301 重定向链接数量,因此我想将子域名到非 www 重定向(子域名为 的情况除外dev)与 HTTP 到 HTTPS 重定向(使用%{HTTP:X-Forwarded-Proto})相结合,因为实例位于负载均衡器后面。

以下是我目前所拥有的内容.htaccess

# move http to https 
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=301]

# Remove leading www 
RewriteCond %{HTTP_HOST} ^www.example.net [NC]
RewriteRule ^(.*)$ https://example.net/$1 [R=301,L]

我目前的实现存在三个问题:

  1. 一个请求http://www.example.net将会有两次重定向。

  2. 与本网站上大多数 www 到非 www 重定向示例一样,它不会重定向ww.wwww.因此我的分析中有很多输入错误的尚未重定向的子域名。

  3. 我想将子域名以及它的兄弟域名dev.从重定向中排除,因为我用于开发和发布阶段。http://dev.example.nethttpsdev.

我该如何将它们结合起来?

答案1

1)一个请求http://www.example.net将会有两次重定向。

只需反转这两条规则即可解决此问题。然后www.example.net在第一次重定向中重定向到 HTTPS,因此无需触发 HTTP 到 HTTPS 的重定向。

(不过,这假设你无意实施高速传输系统- 在这种情况下,你需要将它们保留为两个重定向,因为重定向到同一主机名上的 HTTPS第一的是一项要求。

2) 与本网站上大多数 www 到非 www 重定向示例一样,它不会重定向ww.wwww.因此我的分析中有很多输入错误的尚未重定向的子域名。

ww.通常情况下,对或子域的请求wwww.根本无法解析,因此这通常不是问题。要实现此功能,您必须配置通配符DNS 中的子域并配置服务器以接受此类请求。

^www\.但这可以通过将正则表达式(片段)从 修改为来解决^w{2,4}\.

3)我想将子域名以及它的兄弟域名dev.从重定向中排除,因为我用于开发和发布阶段。http://dev.example.nethttpsdev.

这仅适用于 HTTP 到 HTTPS 规则,因此可以在此处应用附加条件来排除以 开头的主机名dev.

综合以上几点,请尝试以下操作:

# Remove leading ww, www or wwww (and redirect to HTTPS)
RewriteCond %{HTTP_HOST} ^w{2,4}\.example\.net [NC]
RewriteRule (.*) https://example.net/$1 [R=301,L]

# Move http to https (except dev subdomain)
RewriteCond %{HTTP:Host} !^dev\. [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP:Host}%{REQUEST_URI} [R=301,L]

我保留了您的使用方式HTTP:Host(以便访问HostHTTP 请求标头),以防这是负载平衡器的要求?否则,在这里使用服务器变量更为常见HTTP_HOST

!上的前缀条件模式(即)否定正则!^dev\.表达式,因此当Host不是从 开始dev.。(我认为www.dev.不是这样的?)

(.*)与之相同,^(.*)$因为正则表达式默认是贪婪的。

测试前您需要清除浏览器缓存。建议先使用 302(临时)重定向进行测试,以避免任何缓存问题。

答案2

# Remove leading www, always using https regardless of the current URL scheme
RewriteCond %{HTTP_HOST} ^w{2,4}.example.net(?::|$) [NC,NV]
RewriteRule .* https://example.net%{REQUEST_URI} [L,R=301]

# move http to https, except for dev.example.net
RewriteCond %{HTTP:X-Forwarded-Proto} =http [NC,NV]
RewriteCond %{HTTP_HOST} !^dev.example.net(?::|$) [NC,NV]
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  1. 向条件添加了NC( nocase) 标志X-Forwarded-Proto,因为其值似乎不区分大小写,即HTTP = Http = hTTp = http。您可以随意删除它。
  2. 向条件添加了NV( novary) 标志X-Forwarded-Proto以将其隐藏在Vary响应标头中。同样,您可以随意删除它,特别是如果情况并非如此(反向代理会在将其发送到客户端之前自动为您过滤它)或需要正确的缓存行为(否则缓存不会区分http内容https)。
  3. 向标头条件添加了NV( novary) 标志Host,以将其隐藏在Vary响应标头中。如果您的缓存服务器损坏,您也可以将其删除。
  4. 使RewriteRule标志顺序一致(L,R=301并且R=301,L本质上相同)。
  5. 无法www.example.net.but.not.actually.yours.com被识别,但仍然允许例如www.example.net:443
  6. 持续使用%{REQUEST_URI}作为替代品。
  7. 也认识到wwwwww

相关内容