服务器名称

    当通过名称搜索虚拟服务器时,如果名称与多个指定的变体匹配,例如通配符和正则表达式,则将按照优先顺序选择第一个匹配的变体:

    1. 精确的名称
    2. 以星号开头的最长的通配符名称,例如
    3. 以星号结尾的最长的通配符名称,例如 mail.*
    4. 第一个匹配的正则表达式(按照在配置文件中出现的顺序)

    通配符名称只能在名称的开头或者结尾包含一个星号,且只能在点的边界上包含星号。这些名称为 www.*.example.orgw*.example.org 都是无效的。然而,可以使用正则表达式指定这些名称,例如,~^www\..+\.example\.org$”~^w.*\.example\.org$。星号可以匹配多个名称部分。名称 *.example.org 不仅匹配了 www.example.org,还匹配了 www.sub.example.org

    可以使用 .example.org 形式的特殊通配符名称来匹配确切的名称 example.org 和 通配符 *.example.org

    正则表达式名称

    nginx 使用的正则表达式与 Perl 编程语言(PCRE)使用的正则表达式兼容。要使用正则表达式,服务器名称必须以波浪符号开头:

    1. server_name ~^www\d+\.example\.net$;

    否则将被视为确切的名称,或者如果表达式中包含星号,将被视为通配符名称(并且可能是无效的)。别忘了设置 ^$ 锚点。它们在语法上不是必须的,但在逻辑上是需要的。还要注意的是,域名的点应该使用反斜杠转义。正则表达式中的 {} 应该被引号括起:

    1. server_name "~^(?<name>\w\d{1,3}+)\.example\.net$";

    否则 nginx 将无法启动并且显示错误信息:

    1. directive "server_name" is not terminated by ";" in ...

    正则表达式名称捕获到的内容可以作为变量为后面所用:

    1. server {
    2. server_name ~^(www\.)?(?<domain>.+)$;
    3. location / {
    4. root /sites/$domain;
    5. }
    6. }

    PCRE 库使用以下语法捕获名称:

    • ?<name> Perl 5.10 兼容语法,自 PCRE-7.0 起支持
    • ?'name' Perl 5.10 兼容语法,自 PCRE-7.0 起支持

    如果 nginx 无法启动并且显示错误信息:

    说明 PCRE 库比较老,应该尝试使用语法 ?P<name>。捕获也可以使用数字形式:

    1. server {
    2. server_name ~^(www\.)?(.+)$;
    3. location / {
    4. root /sites/$2;
    5. }
    6. }

    有一些服务器名称需要被特别处理。

    如果需要处理一个在不是默认的 块中的没有 Host 头字段的请求,应该指定一个空名称:

    1. server {
    2. listen 80;
    3. server_name example.org www.example.org "";
    4. ...
    5. }

    如果 server 块中没有定义 ,那么 nginx 将使用空名称作为服务器名。

    如果服务器名称被定义为 $hostname(0.9.4),则使用机器的主机名。

    如果有人使用 IP 地址而不是服务器名称来发出请求,则 Host 请求 header 域将包含 IP 地址,可以使用 IP 地址作为服务器名称来处理请求。

    1. server {
    2. listen 80;
    3. server_name example.org
    4. www.example.org
    5. ""
    6. 192.168.1.1
    7. ;
    8. ...
    9. }

    在所有的服务器示例中,可以发现一个奇怪的名称 _

    1. server {
    2. listen 80 default_server;
    3. server_name _;
    4. return 444;
    5. }

    这个名称没有什么特别之处,它只是众多无效域名中的一个,它永远不会与任何真实的名称相交。此外还有其他无效的名称,如 --!@# 也是如此。

    nginx 到 0.6.25 版本支持特殊的名称 *,这常被错误地理解为所有名称。它并不是所有或者通配符服务器名称。相反,它的功能现在是由 server_name_in_redirect 指令提供。现在不推荐使用特殊的名称 *,应该使用 指令。请注意,无法使用 server_name 指令来指定所有名称或者默认服务器。这是 指令的属性,而不是 server_name 的。请参阅 。可以定义监听 *:80*:8080 端口的服务器,并指定一个为 端口的默认服务器,另一个为 *:80 端口的默认服务器。

    国际化名称

    应使用 指令中的ASCII(Punycode)表示来指定国际化域名(IDN

    1. server {
    2. server_name xn--e1afmkfd.xn--80akhbyknj4f; # пример.испытание
    3. ...
    4. }

    首先搜索确切的名称哈希表。如果为找到名称,则会搜索以星号开头的通配符名称的哈希表。如果还是没有找到名称,则搜索以星号结尾的通配符名称哈希。

    搜索通配符哈希表比搜索确切名称的哈希表要慢,因为名称是通过域部分搜索的。请注意,特殊通配符格式 .example.org 存储在通配符哈希表中,而不是确切名称哈希表中。

    由于正则表达式是按顺序验证的,因此是最慢的方法,并且是不可扩展的。

    由于这些原因,最好是尽可能使用确切的名称。例如,如果最常见被请求的服务器名称是 example.orgwww.example.org,则明确定义它们是最有效的:

    1. server {
    2. listen 80;
    3. server_name example.org www.example.org *.example.org;
    4. ...
    5. }

    简化形式:

    1. server {
    2. listen 80;
    3. server_name .example.org;
    4. ...
    5. }

    如果定义了大量的服务器名称,或者定义了非常长的服务器名称,则可能需要调整 http 级别的 和 server_names_hash_bucket_size 指令。 指令的默认值可能等于 32 或者 64 或者其他值。具体取决于 CPU 超高速缓存储器线的大小。如果默认值为 32,并且服务器名称定义为 too.long.server.name.example.org,则 nginx 将无法启动并显示错误信息:

    1. could not build the server_names_hash,
    2. you should increase server_names_hash_bucket_size: 32

    在这种情况下,指令值应该增加到 2 倍:

    如果定义了大量的服务器名称,则会显示另一个错误信息:

    1. could not build the server_names_hash,
    2. you should increase either server_names_hash_max_size: 512
    3. or server_names_hash_bucket_size: 32

    在这种情况下,首先尝试将 server_names_hash_max_size 设置为接近服务器名称数量的数值。如果这样没有用,或者如果 nginx 的启动时间长的无法忍受,那么请尝试增加 的值。

    如果服务器是监听端口的唯一服务器,那么 nginx 将不会验证服务器名称(并且不会为监听端口建立哈希表)。但是,有一个例外。如果服务器名称具有捕获(captures)的正则表达式,则 nginx 必须执行表达式才能获取捕获。

    兼容性

    • 自 0.9.4 起,支持特殊的服务器名称 $hostname
    • 自 0.8.48 起,默认服务器名称的值为空名称 ""
    • 自 0.8.25 其,已经支持命名的正则表达式服务器名称捕获。
    • 自 0.7.40 起,支持正则表达式名称捕获。
    • 自 0.7.12 起,支持空的服务器名称 ""
    • 自 0.6.25 起,支持使用通配符服务器名称和正则表达式作为第一服务器名称。
    • 自 0.6.7 起,支持正则表达式服务名称。
    • 自 0.6.0 起,支持类似 example.* 的通配符。
    • 自 0.3.18 起,支持类似 .example.org