必须配置proxy_set_header X-Forwarded-Proto $scheme并置于proxy_pass前,后端框架需显式信任该头(如Django设SECURE_PROXY_SSL_HEADER、Spring Boot配forward-headers-strategy),否则将导致重定向异常、Secure Cookie失效等问题。

反代架构下 HTTPS 卸载(即 SSL Termination)后,后端服务器(如 Nginx、Tomcat、Apache)收到的是 HTTP 请求,但浏览器访问的是 HTTPS 页面。此时若后端应用未正确识别原始协议,就会生成 http:// 开头的资源链接(如 CSS、JS、图片、重定向 Location),导致页面加载混合内容(Mixed Content)或跳转回 HTTP,破坏安全性和功能。
确认问题根源:后端是否感知真实协议
HTTPS 卸载后,反代(如 CDN、负载均衡器、前置 Nginx)会将请求以 HTTP 形式转发给后端,并在请求头中添加标识原始协议的字段,最常见的是:
- X-Forwarded-Proto: https(标准推荐)
- X-Forwarded-Protocol: https
- X-Url-Scheme: https
如果后端代码或框架未读取这些头,仍按自身接收协议(HTTP)生成 URL,就必然出错。可通过浏览器开发者工具 Network 面板查看响应 HTML 中的资源链接,或打印后端接收到的请求头验证。
后端应用层修复:适配 X-Forwarded-Proto
让业务代码信任反代传递的协议信息,是根本解法。不同环境处理方式如下:
-
PHP 应用:在入口或配置中判断
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https',并设置$_SERVER['HTTPS'] = 'on',确保is_https()、URL 生成函数等行为正确 -
Java(Spring Boot):启用
server.forward-headers-strategy=framework,并配置server.tomcat.remote-ip-header=x-forwarded-for和server.tomcat.protocol-header=x-forwarded-proto -
Node.js(Express):启用
app.set('trust proxy', true),它会自动解析X-Forwarded-Proto并设置req.protocol -
WordPress:在
wp-config.php添加:if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; }
反代层兜底:强制升级不安全资源请求
当无法修改后端代码(如老旧系统、第三方 SaaS 前置代理),可在反代层注入安全策略,让浏览器自动将 HTTP 资源升级为 HTTPS:
- 在反代响应头中添加:
Content-Security-Policy: upgrade-insecure-requests - 或对 HTML 响应做流式重写(需支持,如 Nginx 的
sub_filter或 Envoy 的 regex rewrite),将src="http://替换为src="https://(慎用,可能误改非 URL 内容)
注意:该策略仅对主动型混合内容(脚本、样式、iframe)有效,且要求浏览器支持 CSP Level 2(Chrome 43+、Firefox 48+ 等主流版本均支持)。
静态资源与重定向:统一协议生成逻辑
除动态页面外,以下两类也常出问题:
-
重定向 Location 头:后端返回 301/302 时若写死
http://,用户将被跳离 HTTPS。务必使用相对重定向(Location: /path)或基于X-Forwarded-Proto动态构造完整 URL -
CDN 或静态资源路径:避免硬编码协议。优先使用协议相对 URL(
//cdn.example.com/style.css),或由后端模板根据X-Forwarded-Proto输出https://前缀
若第三方 CDN 不支持 HTTPS,应更换或为其配置独立 SSL 证书,而非妥协于混合内容。

















