应配置 proxy_set_header X-Forwarded-Proto $scheme; 透传协议类型,避免写死;多层代理时仅最外层设置,后端需显式启用该头解析,并同步传递 Host 和 X-Real-IP 等头以还原客户端上下文。

要让后端知道客户端最初用的是 HTTP 还是 HTTPS,Nginx 不能透传 HTTP 协议版本(比如 HTTP/1.1),因为那是请求行的一部分,无法通过请求头传递。真正该传的是协议类型,也就是 http 或 https,靠的是 X-Forwarded-Proto 这个标准头。
配置 X-Forwarded-Proto 透传协议类型
在对应的 location 块里加上这行:
proxy_set_header X-Forwarded-Proto $scheme;
$scheme 是 Nginx 内置变量,会自动取值为 http 或 https,取决于客户端连接 Nginx 时用的协议。不要写死成 https,否则 HTTP 请求也会被误标。
注意多层代理时的覆盖风险
如果请求经过 CDN、WAF 或前置负载均衡,X-Forwarded-Proto 可能已被上游设置。Nginx 默认会覆盖它:
- 最稳妥的做法:只在最外层(即直面客户端)的 Nginx 上设置该头,内层代理不再重复设置
- 若必须信任上游值,需配合
map指令做条件判断,或改用proxy_pass_request_headers off;后手动透传,但要严格校验来源 IP 是否可信
后端必须主动读取并启用该头
Nginx 只负责发,后端框架默认不解析这个头。需要显式开启支持:
- Spring Boot:设
server.forward-headers-strategy=framework,并确认 Tomcat 启用了RemoteIpValve - Flask:用
ProxyFix中间件,指定x_proto=1 - Express:调用
app.set('trust proxy', true),确保req.protocol返回正确值
别忘了同步传 Host 和真实 IP
协议头不是孤立的,后端常结合 Host 和 X-Real-IP 做安全判断或生成跳转链接:
proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
这些头和 X-Forwarded-Proto 一起配置,才能还原完整的客户端上下文。


















