proxy_set_header 不直接实现域名重写,而是通过设置 host 等请求头让后端“看到”期望域名;需配合 rewrite 顺序及 x-forwarded-* 头确保路径、协议与原始访问信息一致。

在 Nginx 中,proxy_set_header 本身**不直接实现域名重写**,它只是设置发往后端服务器的 HTTP 请求头。但通过合理配置请求头(尤其是 Host),可以间接让后端服务“看到”你期望的域名,从而实现逻辑上的“域名重写传递”。关键在于控制后端接收到的 Host 头和原始请求路径的一致性。
明确 Host 头的作用
后端应用(如 Python Flask、Node.js、PHP 等)通常依赖 Host 请求头来生成绝对 URL、做虚拟主机路由或校验来源。默认情况下,Nginx 反向代理会把客户端原始的 Host 头原样转发;若需改变,必须显式用 proxy_set_header Host ... 覆盖。
- 不设置
proxy_set_header Host→ 后端收到的是用户访问 Nginx 时使用的域名(例如user.example.com) - 设为固定值(如
proxy_set_header Host backend-api.internal;)→ 后端始终看到该值,与用户请求无关 - 设为变量(如
proxy_set_header Host $host;或$http_host;)→ 可保留原始 Host,也可按需替换
常见域名重写传递场景与写法
典型需求是:用户访问 api.example.com,Nginx 代理到 127.0.0.1:8000,但希望后端认为请求来自 api.example.com(而非内网地址或默认 host)。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
保持原始域名:用
$host(不含端口)或$http_host(含端口,更完整)proxy_set_header Host $http_host; -
强制指定域名:适用于后端只认某一个域名
proxy_set_header Host api.company.local; -
根据 location 动态设置:不同路径映射不同后端,各带对应 Host
location /v1/ { proxy_set_header Host v1.api.internal; proxy_pass http://backend-v1; }
配合 rewrite 实现路径+域名协同传递
单纯改 Host 头还不够——如果同时需要修改 URI(比如把 /api/v1/... 去掉前缀再转发),应先 rewrite 再设置头,避免后端收到错误路径。
- 错误顺序(Host 已发,rewrite 晚于 header 设置):
proxy_set_header Host api.example.com;<br>rewrite ^/api/(.*)$ /$1 break;
→ rewrite 不影响已设置的 Host,但可能让后端路径错乱 - 推荐顺序:
rewrite ^/api/(.*)$ /$1 break;<br>proxy_set_header Host api.example.com;<br>proxy_pass http://backend;
注意 X-Forwarded-* 系列头的补充作用
proxy_set_header 还常搭配 X-Forwarded-For、X-Forwarded-Proto 和 X-Forwarded-Host,帮助后端识别真实客户端信息:
-
proxy_set_header X-Forwarded-For $remote_addr;→ 传真实 IP -
proxy_set_header X-Forwarded-Proto $scheme;→ 告诉后端是 http 还是 https -
proxy_set_header X-Forwarded-Host $host;→ 记录用户最初访问的 Host,供后端构造跳转链接










