Nginx变量$ host,$ http_host和$ server_name有什么区别?


42

是什么这三个变量的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/;
        }

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


我意识到以后我什至不需要指定,$scheme并且$host... return 301 /forum/index.php?posts/$arg_p/;可以正常工作。
杰夫·威德曼

大多数浏览器都可以重定向使用相对URL,但是标准(w3.org/Protocols/rfc2616/rfc2616-sec14.html)要求Location标头中包含绝对URL 。
克苏鲁2015年

Answers:


54

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

区别在nginx文档中说明

  • $host 包含“按此优先顺序:请求行中的主机名,或“主机”请求标头字段中的主机名,或与请求匹配的服务器名”
  • $http_host 如果请求中包含HTTP“主机”标头字段的内容,则包含该内容
  • $server_name包含server_name处理请求的虚拟主机的,如nginx配置中所定义。如果a server包含多个server_names,则此变量中仅存在第一个。

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

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

只有$host变量说明了用户代理在形成HTTP请求时可能执行的所有操作。


2
另一方面,$server_nameHost:来自UA的字段可能包含任意内容时,此方法是安全的。
克苏鲁2015年

1
$ http_host是否重命名为$ hostname?我在Nginx doc中找不到这样的变量。$ hostname是我猜中最相似的一个。
darkbaby123 '16

3
@ darkbaby123不,它没有重命名为任何东西。请参阅文档
迈克尔·汉普顿

1
现在我明白了http_ <name>变量的含义。谢谢!
darkbaby123 '16

0

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

$host具有端口号,而$http_hostDO包括端口号。

编辑:并非总是如此。

我设置了标题“始终为add_header Y-blog-http_host“ $ http_host”;”

然后curl -I -L domain.com:80(或443),标题完全不显示端口号。已通过nginx-extra 1.10.3验证。是因为它是常见的http(s)端口或nginx配置?此评论仅表示事情并非总是按照您的想法行事。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.