我正在尝试减少服务器上的 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]
我目前的实现存在三个问题:
一个请求
http://www.example.net
将会有两次重定向。与本网站上大多数 www 到非 www 重定向示例一样,它不会重定向
ww.
,wwww.
因此我的分析中有很多输入错误的尚未重定向的子域名。我想将子域名以及它的兄弟域名
dev.
从重定向中排除,因为我用于开发和发布阶段。http://dev.example.net
https
dev.
我该如何将它们结合起来?
答案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.net
https
dev.
这仅适用于 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
(以便访问Host
HTTP 请求标头),以防这是负载平衡器的要求?否则,在这里使用服务器变量更为常见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]
- 向条件添加了
NC
(nocase
) 标志X-Forwarded-Proto
,因为其值似乎不区分大小写,即HTTP = Http = hTTp = http
。您可以随意删除它。 - 向条件添加了
NV
(novary
) 标志X-Forwarded-Proto
以将其隐藏在Vary
响应标头中。同样,您可以随意删除它,特别是如果情况并非如此(反向代理会在将其发送到客户端之前自动为您过滤它)或需要正确的缓存行为(否则缓存不会区分http
内容https
)。 - 向标头条件添加了
NV
(novary
) 标志Host
,以将其隐藏在Vary
响应标头中。如果您的缓存服务器损坏,您也可以将其删除。 - 使
RewriteRule
标志顺序一致(L,R=301
并且R=301,L
本质上相同)。 - 无法
www.example.net.but.not.actually.yours.com
被识别,但仍然允许例如www.example.net:443
。 - 持续使用
%{REQUEST_URI}
作为替代品。 - 也认识到
ww
和wwww
。