Nginx 变量 $host、$http_host 和 $server_name 之间有什么区别?

Jef*_*man 66 rewrite nginx

是什么这三个变量的Nginx之间的差异$host$http_host以及$server_name

我有一个重写规则,我不确定应该使用哪一个:

location = /vb/showthread.php {
    # /vb/showthread.php?50271-What-s-happening&p=846039
    if ($arg_p) {
        return 301 $scheme://$host/forum/index.php?posts/$arg_p/;
        }
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个答案,不仅要说“在重写规则中使用 ___ 变量”,还要解释它们之间的理论差异。

Mic*_*ton 73

您几乎应该总是使用$host,因为无论用户代理如何行为,它都是唯一保证具有合理性的东西,除非您特别需要其他变量之一的语义。

nginx 文档中解释了差异:

  • $host 包含“按优先顺序:请求行中的主机名,或‘主机’请求头字段中的主机名,或与请求匹配的服务器名”
  • $http_host 包含 HTTP“主机”标头字段的内容(如果它存在于请求中)
  • $server_name包含server_name处理请求的虚拟主机的 ,因为它是在 nginx 配置中定义的。如果 aserver包含多个server_names,则此变量中只会出现第一个。

由于用户代理在请求行而不是在 Host: 标头中发送主机名是合法的,尽管除了连接到代理时很少这样做,但您必须考虑到这一点。

您还必须考虑用户代理根本不发送主机名的情况,例如古老的 HTTP/1.0 请求和现代编写的糟糕软件。您可以通过将它们转移到一个不提供任何服务的全能虚拟主机来实现这一点,如果您为多个网站提供服务,或者如果您的服务器上只有一个网站,您可以通过一个虚拟主机处理所有内容. 在后一种情况下,您也必须考虑到这一点。

只有$host变量说明了用户代理在形成 HTTP 请求时可能做的所有事情。

  • 另一方面,当来自 UA 的 `Host:` 字段可能包含任意内容时,`$server_name` 是安全的。 (3认同)
  • @darkbaby123 不,它没有重命名为任何东西。请参阅[文档](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_http_)。 (3认同)
  • 啊现在我明白了 http_<name> 变量的含义。谢谢你! (2认同)

Moh*_*din 6

我想补充已接受的答案中未提及的另一个重要观点。

$host没有端口号,但包含$http_host端口号。

编辑:并不总是。

我设置了一个标头“add_header Y-blog-http_host “$http_host”始终;”

然后curl -I -L domain.com:80(或 443)并且标头根本不显示端口号。使用 nginx-extra 1.10.3 进行验证。是因为它是常见的 http(s) 端口还是 nginx 配置?此评论只是想说事情并不总是按照您的想法行事。