Nginx 如何强制(重定向到)HTTPS?

在监听 80 的 server 块里 return 301 https://$host$request_uri 即可全站跳 HTTPS;配合 HSTS 头让浏览器之后直连 HTTPS。本文给出完整配置与证书、回环等注意事项。

最佳实践
Nginx 如何强制(重定向到)HTTPS?封面

标准做法:80 端口的 server 块只干一件事——return 301 https://$host$request_uri;,把所有 HTTP 请求 301 到同域名同路径的 HTTPS 地址;443 的 server 块正常配 SSL 证书与业务。再加 HSTS 响应头,让浏览器后续直接走 HTTPS,连跳转都省掉。

完整配置

# HTTP:全部 301 到 HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

# HTTPS:正常业务
server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # HSTS:让浏览器记住"以后只走 HTTPS"(确认全站 HTTPS 稳定后再开)
    add_header Strict-Transport-Security "max-age=31536000" always;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;   # 让后端知道原始是 https
    }
}

要点:$host 保留用户访问的域名(www 与否不变),$request_uri 保留完整路径与参数。

注意事项

  1. 证书先就位:443 站点证书配好并验证后再开强制跳转,否则用户直接撞证书错误
  2. 健康检查例外:负载均衡器的 HTTP 健康检查被 301 会判失败,给检查路径开例外:
location = /healthz { return 200 "ok"; }   # 放在 80 的 server 块,先于 return 301
  1. HSTS 谨慎开长 max-age:一旦下发,浏览器在 max-age 内只认 HTTPS,证书出问题用户没有任何绕过的余地
  2. 后端应用感知X-Forwarded-Proto 头带给后端,否则后端生成的重定向/链接可能还是 http(混合内容警告)

验证

curl -I http://example.com/some/page?a=1
# HTTP/1.1 301 Moved Permanently
# Location: https://example.com/some/page?a=1

观测云对照

跳转与证书都有监控点。 拨测同时监控 HTTP→HTTPS 跳转正确性与证书有效期(到期前告警);Nginx 日志里 301 量与 4xx/5xx 比例也可在观测云看板跟踪。

常见问题(FAQ)

Q:用 301 还是 302?
A:永久迁移用 301(浏览器会缓存跳转,SEO 权重传递);临时用途才 302。

Q:if ($scheme = http) 写法为什么不推荐?
A:Nginx 官方"If Is Evil"——server 块级 if 在 rewrite 阶段有诸多陷阱;独立 80 server 块 + return 是最干净的形式。

Q:API 接口也要强制跳转吗?
A:要,但注意 301 对 POST 的客户端重发行为不一;更稳妥是 API 只开 443,80 直接拒绝连接。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台