Nginx:如何仅将主域与 server_name 匹配
Posted
技术标签:
【中文标题】Nginx:如何仅将主域与 server_name 匹配【英文标题】:Nginx: How to match ONLY the main domain with server_name 【发布时间】:2021-02-20 18:57:05 【问题描述】:我的目标是将example.com
重定向到www.example.com
,而不将any 子域重定向到www
。
这就是我所拥有的:
server
listen 443;
server_name example.com;
return 301 https://www.$server_name$request_uri;
使用这种配置,每个子域(例如:foo.example.com
)都会被重定向到www.example.com
,而不仅仅是没有子域的主域(example.com
),正如我所愿。
我尝试清理缓存(也可以从其他浏览器执行),结果相同。
编辑:
server_name
与子域匹配的证据是,如果我将重定向 url 更改为:https://www.$host$request_uri
,则:
foo.example.com
被重定向到 www.foo.example.com
。
【问题讨论】:
此服务器块也是处理任何与任何 server_name 不匹配的请求的默认服务器块。见how nginx processes a request。您需要定义一个包罗万象的服务器。见this answer。 【参考方案1】:其实example.com
确实只匹配主域。
但如果hostname
不匹配任何server_name
(在您的示例中,您的子域不匹配,因为主域只有一个服务器规则),默认服务器将被使用,if you didn't specify it with the default_server
tag in the listen parameter, it uses by default the first server,在您的情况下,它是主域的重定向规则。
TD;TR
您的子域不匹配任何规则,因此它们被回调到您设置的唯一规则,即重定向。
您需要为子域制定特定规则:
server
listen 443;
server_name *.example.com;
# do something, or leave it blank for default nginx page
这将阻止子域使用默认服务器,因此被重定向到www
,但它们没有配置为什么都不做,因此将显示默认的 nginx 页面。我建议直接为每个子域指定您想要的行为,或者将注释替换为所有子域的实际预期行为。
【讨论】:
【参考方案2】:尝试使用多个server_name
指令:
server
listen 443;
server_name example.com;
return 301 https://www.$server_name$request_uri;
server
listen 443;
server_name ~^(?<name>\w+)\.example\.com$;
... # insert your directives (location etc.)
如nginx
documentation 上指定:
按名称搜索虚拟服务器时,如果名称匹配更多 比指定的变体之一,例如通配符名称和 正则表达式匹配,将选择第一个匹配的变体, 按以下优先顺序:
确切名称 以星号开头的最长通配符名称,例如“*.example.org” 以星号结尾的最长通配符名称,例如“邮件。*” 第一个匹配的正则表达式(按配置文件中出现的顺序)
【讨论】:
将 foo.example.com 重定向到 foo.example.com 对我来说似乎有点奇怪 正如我所料,这会导致重定向循环。 如果删除 foo.example.org 的return
会发生什么?
好的。我需要子域的特定规则。
您的更新解决方案可能有效,但我认为最好使用 * 作为通配符而不是正则表达式。这很有帮助,所以为您的方法 +1。以上是关于Nginx:如何仅将主域与 server_name 匹配的主要内容,如果未能解决你的问题,请参考以下文章
PHP:将主域重定向到https:// www,子域重定向到https://(不带www)
.htaccess:将主域重定向到https:// www,子域重定向到https://(不带www)