1. 为什么需要区分$http_host、$host和$proxy_host
在Nginx配置中处理HTTP请求时,我们经常会遇到需要获取或设置主机名的情况。这时候$http_host、$host和$proxy_host这三个变量就会频繁出现在配置文件中。很多开发者在使用时容易混淆它们,导致一些微妙的配置错误。
这三个变量的核心区别在于它们的来源和作用场景:
- $http_host直接来自HTTP请求头中的Host字段
- $host是Nginx内部处理后的规范化主机名
- $proxy_host则与反向代理场景密切相关
理解它们的差异对于正确配置Nginx至关重要,特别是在以下场景:
- 需要精确控制传递给后端服务器的Host头时
- 在多域名环境下需要区分请求的原始目标
- 在反向代理配置中需要保持URL重写的正确性
- 日志记录中需要包含准确的域名信息
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 变量定义与核心特性解析
2.1 $http_host:原始请求的忠实记录者
$http_host变量直接对应客户端HTTP请求头中的Host字段。它的特点是:
- 完全保留客户端发送的原始值,包括端口号(如果存在)
- 如果请求中没有Host头,则该变量为空
- 大小写敏感,保留原始的大小写形式
典型值为:"example.com:8080"或"api.example.org"
在Nginx配置中,$http_host常用于:
nginx复制proxy_set_header Host $http_host; # 将原始Host头传递给后端
2.2 $host:Nginx的规范化处理结果
$host变量是Nginx对Host头进行规范化处理后的结果,具有以下特性:
- 自动去除端口号(即使原始请求包含端口)
- 如果请求没有Host头,会fallback到server_name指令的第一个值
- 统一转换为小写形式
- 不包含默认端口(80或443)
典型值为:"example.com"或"api.example.org"
常见使用场景:
nginx复制if ($host != 'example.com') {
return 301 https://example.com$request_uri;
}
2.3 $proxy_host:反向代理的专属变量
$proxy_host变量专门用于反向代理场景,表示proxy_pass指令中指定的上游服务器地址:
- 包含完整的主机名和端口(除非是默认端口)
- 当proxy_pass指向upstream名称时,值为upstream名称
- 默认端口(80/443)会被省略
典型值为:"backend-server:8080"或"upstream-backend"
典型配置示例:
nginx复制location / {
proxy_pass http://backend;
proxy_set_header X-Forwarded-Host $proxy_host;
}
3. 端口号处理行为的深度对比
端口号的处理是这三个变量最显著的区别点之一,也是实际配置中最容易出错的地方。
