当前页面使用了 AMP 加速。如需访问完整页面,App-Scope 还准备了 RWD 版 »

Nginx 学习笔记 (a2) - $host / $http_host / $server_name 区别


变量 $host

$host in this order of precedence: host name from the request line, or host name from the “Host” request header field, or the server name matching a request

$host 的值,首先是请求行 (Request Line) 中的 host name,打个比方,GET http://example.com/ HTTP/1.1 中的 host name 就是 example.com;然后是请求头 (Request Header) 内 Host 字段的值;最后是匹配成功的 server name,有点儿“调剂”的意思。值得一提的是,$host 总是小写且不带端口号。

关于请求行和请求头,请参阅


变量 $http_host

The ngx_http_core_module module supports embedded variables with names matching the Apache Server variables. These are variables representing client request header fields, such as $http_user_agent, $http_cookie, and so on.

$http_host 的值,其实就是请求头中 Host 字段的值 (同理可得请求头中任意字段的值,如 User-Agent 就可以以 $http_user_agent 来调用,更多举例见),可简单理解为 (但不等同) $host:$server_port

另外 $proxy_port$server_port 的区别在于,前者为 backend 的端口,通常会隐藏起来,如 8080;前者为客户端访问 frontend 使用的端口,如 80。


变量 $server_name

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

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

$server_name 的值,是实际处理该请求的 server block 的 server_name。Nginx 分发请求时,会依据客户端请求的 Host 按优先级逐次匹配各 server name,路由到符合条件的第一个 server。首先做精确匹配,其次查找通配符 * 开头的,再次查找通配符 * 结尾的,从次以正则表达式做模糊匹配。

若请求的 Host 匹配不上 (或许根本是空值),则分派给默认的 Virtual Host 来处理。至于哪个是默认的 server,可以在 listen 指令中附上 default_server 参数来指定。若没有指定的话,该请求将会走 http block 里面的第一个 server block (减少攻击面计,实务上应返回 444 No Response 以关闭连接,方法见 反制手段 3 @ Nginx 学习笔记 (5) - 被反代被镜像了怎么办?)。

倘若对 Nginx 处理请求的过程感兴趣,由此可以做更深入了解。