最直接有效的方式是用两个完全分离的server块:一个仅监听80端口并用return 301跳转https,另一个监听443端口配置ssl证书及业务逻辑,需校验语法、重载服务,并注意安全组、文件权限与cdn协同。

最直接有效的方式,是用两个完全分离的 server 块:一个专管 HTTP(80 端口)跳转,另一个专管 HTTPS(443 端口)服务。不混用、不嵌套、不依赖 if 判断,结构清晰,出错率低。
只监听 80 端口的跳转 server 块
这个块不做任何业务处理,只负责“一接就跳”:
- 必须写
listen 80;,不能加ssl或证书相关指令 - 用
return 301 https://$host$request_uri;——$host保留原始域名(如 www 或非 www),$request_uri完整携带路径和参数,不会丢内容 -
server_name要写全你实际使用的域名,例如server_name example.com www.example.com;,否则可能匹配失败 - 不要放
root、index、location等无关指令,保持纯粹
独立存在的 443 端口 HTTPS server 块
跳转能生效,前提是 HTTPS 本身能正常响应:
- 必须另起一个
server块,明确写listen 443 ssl http2; - 正确指定证书路径:
ssl_certificate指向fullchain.pem,ssl_certificate_key指向privkey.pem - 建议加上 HSTS 头:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;,提升安全性 - 这里才能放你的真实业务配置,比如
root、location、proxy_pass等
配置后必须验证并重载
改完不能直接刷网页看效果,得走标准流程:
- 运行
sudo nginx -t,提示successful才算语法通过 - 执行
sudo systemctl reload nginx(或sudo nginx -s reload)让新规则生效 - 用
curl -I http://yourdomain.com检查响应头,确认返回HTTP/1.1 301 Moved Permanently和正确的Location地址 - 浏览器用无痕模式访问 HTTP 地址,观察是否秒变 HTTPS 且锁图标正常
容易踩坑的几个关键点
跳转失败,往往不是逻辑写错,而是环境细节被忽略:
- 云服务器(如阿里云、腾讯云)的安全组必须放行 443 端口,否则跳过去就卡住
- 私钥文件(
privkey.pem)权限不能是 644,Nginx 默认以www-data或nobody用户读取,应设为chmod 600 - 别用
rewrite替代return:rewrite ... permanent是 301,但有正则开销和变量风险;return 301更轻量、更确定 - 如果用了 CDN(如 Cloudflare),要确认源站 Nginx 是否仍需跳转——若 CDN 已开启“强制 HTTPS”,源站再跳一次就会报
ERR_TOO_MANY_REDIRECTS











