在Nginx中,变量$host和$http_host之间的区别是什么?
$host是Core模块的一个变量。
美元的主机
此变量等于请求或报头中的行Host 如果Host头不是,则处理请求的服务器名 可用。
这个变量的值可能与$http_host的值不同 情况:1)当主机输入头不存在或有一个空值时, $host = server_name指令的值;2)当值 的主机包含端口号,$ Host不包含该端口号。 $host的值从0.8.17开始总是小写的。
$http_host也是同一个模块的一个变量,但是你找不到它的名字,因为它一般定义为$http_HEADER (ref)。
http_HEADER美元
HTTP请求头的值,当转换为小写,'破折号'转换为'下划线'时,例如$http_user_agent, $http_referer…;
总结:
$http_host总是等于http_host请求头。 $host等于$http_host,小写,没有端口号(如果存在),除非http_host不存在或为空值。在这种情况下,$host等于处理请求的服务器的server_name指令的值。
公认的答案及其注释似乎(不再)是正确的。文档(http://nginx.org/en/docs/http/ngx_http_core_module.html#var_host)说$host是
按优先级顺序:来自请求行的主机名,或者来自“host”请求报头字段的主机名,或者匹配请求的服务器名
因此$http_host总是Host报头字段的值。如果请求行(如果指定)中的主机与host报头字段不同,则它们可能不同。或者如果没有设置Host报头。
server_name只匹配Host报头字段(http://nginx.org/en/docs/http/request_processing.html),因此$ Host可能与匹配的server_name不同。
http_host美元
$http_host总是等于主机请求报头字段
Host: example.org
美元的主机
$host的优先级顺序(从高到低):
来自请求行的主机名 获取http://example.org/test/ HTTP/1.1 主机请求报头字段 匹配请求的server_name(在Nginx配置中),即使server_name是通配符(Ex: server_name *.example.org;)
来自请求行的主机名
当打开URL http://example.org/test/…
大多数浏览器都是这样发送请求的
GET /test/ HTTP/1.1
Host: example.org
大多数浏览器不会这样发送请求(但这是有效的请求)
GET http://example.org/test/ HTTP/1.1
验证
Nginx测试配置
server {
listen 80;
server_name *.example.org;
location / {
default_type "text/plain";
return 200 "[host] = $host";
}
}
当一切都存在时……
$host =请求行的主机名
curl http://127.0.0.1 -v \
--request-target http://request.example.org/test/ \
--path-as-is \
-H "Host: host.example.org"
这个命令将
连接到127.0.0.1 发送请求路径为GET http://request.example.org/test/ HTTP/1.1 “主机头”设置为“主机:host.example.org”
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET http://request.example.org/test/ HTTP/1.1
> Host: host.example.org
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Fri, 21 Oct 2022 02:00:56 GMT
< Content-Type: text/plain
< Content-Length: 28
< Connection: keep-alive
<
* Connection #0 to host 127.0.0.1 left intact
[host] = request.example.org
当只有主机头存在时…
$host =主机头
curl http://127.0.0.1/test/ -v \
-H "Host: host.example.org"
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /test/ HTTP/1.1
> Host: host.example.org
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Fri, 21 Oct 2022 02:01:37 GMT
< Content-Type: text/plain
< Content-Length: 25
< Connection: keep-alive
<
* Connection #0 to host 127.0.0.1 left intact
[host] = host.example.org
当不存在时……
$host = server_name(在Nginx配置中)
# HTTP 1.1 must have Host header, so use HTTP 1.0
curl http://127.0.0.1/test/ -v -H "Host:" -0
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /test/ HTTP/1.0
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Fri, 21 Oct 2022 02:02:20 GMT
< Content-Type: text/plain
< Content-Length: 22
< Connection: close
<
* Closing connection 0
[host] = *.example.org
参考:ngx_http_core_module, Nginx $主机验证
推荐文章
- Nginx中$host和$http_host的区别是什么
- Nginx 403禁止所有文件
- 在Spring配置文件中使用bean id和名称的区别
- 如何获得当前屏幕方向?
- 什么是http头“X-XSS-Protection”?
- 在哪里放置和如何在基于servlet的应用程序读取配置资源文件?
- 使用curl在PHP中获取HTTP代码
- 为跨源请求设置cookie
- Nginx missing sites-available目录
- 什么是“升级-不安全-请求”HTTP报头?
- 向Angular HttpClient添加一个HTTP头并不会发送这个头,为什么?
- 获取Spring应用程序背景信息
- Nginx - client_max_body_size没有效果
- 如何在NGINX配置中对两个位置有相同的规则?
- Eclipse字体和背景颜色