https访问失败常因rewrite规则强制降级到http,如return 301 http://$host$request_uri;或https server块缺失、误配导致协议降级;需检查server块匹配、x-forwarded-proto头设置及rewrite末尾斜杠与break指令,并用curl而非浏览器验证。

检查 rewrite 规则是否强制跳转到 HTTP
很多 HTTPS 访问失败,其实不是证书或端口问题,而是 rewrite 规则把 HTTPS 请求又重写回了 HTTP 地址。比如配置中写了:
- return 301 http://$host$request_uri; —— 这会把所有请求(包括 HTTPS)都降级到 HTTP,浏览器直接拒绝加载
-
if ($scheme = http) { return 301 https://$host$request_uri; } —— 这个逻辑本身没问题,但如果漏写了
scheme判断条件,或放在了错误的 server 块里,就可能被其他规则覆盖
确认 rewrite 所在的 server 块是否匹配 HTTPS 流量
rewrite 只在它所属的 server 块内生效。常见错误是:
- 把 HTTPS 的 rewrite 写在了监听 80 端口的 server 块里,而监听 443 的 server 块里什么都没配,导致 HTTPS 请求进来了却没做任何处理
- 两个 server 块都写了 rewrite,但 443 块里用了
return 301 http://...,形成反向降级 - 使用了
if判断$host或$request_uri,但没加$scheme,结果在 HTTPS 下误触发跳转
避免在 proxy_pass 前用 rewrite 改写路径时丢失协议信息
当 Nginx 作为反向代理且后端是 HTTP 服务时,前端 HTTPS 请求经过 rewrite 后再 proxy_pass,容易因路径改写不完整导致后端返回的重定向 Location 头仍是 HTTP 地址。关键点是:
- 确保
proxy_set_header X-Forwarded-Proto $scheme;已启用,让后端知道原始请求是 HTTPS - rewrite 后的
proxy_pass目标地址末尾要有斜杠(如http://backend/),否则路径拼接可能出错,引发 301 循环或 404 - 如果 rewrite 用于去除前缀(如
rewrite ^/api/(.*)$ /$1 break;),必须配合break,不能用redirect或permanent
用 nginx -t + curl 验证 rewrite 行为
不要只靠浏览器测试,浏览器缓存 301、自动重试会掩盖真实逻辑。建议:
- 执行 nginx -t 确保语法无误,再 nginx -s reload
- 用 curl 模拟请求:curl -I https://yourdomain.com/path,观察返回的
Location头是否为 HTTPS 地址 - 加 -v 参数看完整跳转链:curl -v https://yourdomain.com,确认是否有多余跳转或协议降级











