Nginx:如何仅将主域与 server_name 匹配

Nginx: How to match ONLY the main domain with server_name

我的目标是将 example.com 重定向到 www.example.com 而不是将 任何 子域重定向到 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 指令:

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 中指定:

When searching for a virtual server by name, if name matches more than one of the specified variants, e.g. both wildcard name and regular expression match, the first matching variant will be chosen, in the following order of precedence:

  1. exact name
  2. longest wildcard name starting with an asterisk, e.g. “*.example.org”
  3. longest wildcard name ending with an asterisk, e.g. “mail.*”
  4. first matching regular expression (in order of appearance in a configuration file)

实际上,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 页面。我建议直接为每个子域指定您想要的行为,或者将注释替换为所有子域的实际预期行为。