使用 proxy_set_header Host $host 可将客户端原始 Host 头原样传递给后端,因 $host 优先取请求行或请求头中的域名(自动去端口),动态适配多域名场景,避免误用 $http_host 或 $server_name。

使用 proxy_set_header Host $host 就是为了在反向代理时把客户端原始请求的域名(即 Host 请求头)原样传递给后端服务,从而让后端能正确识别和响应对应域名的请求。关键在于理解 $host 的行为和 Nginx 的解析逻辑。
确保 $host 取的是真实请求头中的域名
$host 是 Nginx 内置变量,它的值按以下优先级确定:
- 请求行中的 Host 字符串(如
GET / HTTP/1.1后面的域名) - 若请求行无 Host,则取请求头中
Host:字段的值 - 若两者都为空,则为服务器名(
server_name),但这种情况极少
只要客户端发来的 HTTP 请求里带了正确的 Host 头(浏览器、curl 默认都会带),$host 就会如实反映原始域名,无需额外配置。
避免被 $http_host 或 $server_name 干扰
常见误区是误用 $http_host 或硬写 $server_name:
-
$http_host会保留端口(如example.com:8080),而$host自动剥离端口,更符合后端通常期望的纯域名格式 -
$server_name是静态配置值,无法适配多域名共用一个 server 块的场景,会导致所有请求都变成同一个 Host
所以保持 proxy_set_header Host $host; 即可,不要改成其他变量。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
检查是否被 upstream 或 rewrite 改写过 Host
如果发现后端收到的 Host 不对,排查以下两点:
- 确认没有在 location 或 upstream 中重复设置
proxy_set_header Host ...,覆盖了前面的设置 - 确认没有用
rewrite或proxy_redirect修改请求头或重定向逻辑,间接影响 Host 行为
最简验证方式:在后端加个日志,打印接收到的 Host 头,再对比 Nginx access log 中的 $host 值是否一致。
多域名共用同一 proxy 配置时依然有效
比如你用一个 server 块监听 80 端口,同时处理 a.example.com 和 b.example.com:
- 当用户访问
a.example.com,$host就是a.example.com - 当用户访问
b.example.com,$host就是b.example.com -
proxy_set_header Host $host;会自动区分,无需为每个域名单独写 location
这就是 $host 的动态性优势——它随请求变化,不是静态字符串。

















