最推荐的方式是单独配置http server块监听80端口并用return 301跳转https,同时独立配置https server块监听443端口提供加密服务,二者必须分离且严格遵循语法、权限与验证流程。

直接在 Nginx 配置中加一个专用于 HTTP 的 server 块,监听 80 端口并用 return 301 跳转,是最简洁、高效且推荐的方式。关键不是“怎么跳”,而是确保跳得准、跳得稳、不循环、不报错。
单独配置 HTTP 监听块(80 端口)
这个 server 块只做一件事:收所有 HTTP 请求,原路跳 HTTPS。它不能包含任何 SSL 相关指令,否则会启动失败。
- 必须写
listen 80;,建议加上default_server防止未匹配域名的请求误入其他站点 - 用
server_name _;或具体域名(如server_name example.com www.example.com;),避免通配冲突 - 跳转语句统一用:
return 301 https://$host$request_uri;
其中$host保留用户访问的原始域名(含 www 或无 www),$request_uri完整保留路径和查询参数(比如/login?next=/admin)
独立配置 HTTPS 服务块(443 端口)
这个块负责真正提供加密服务,与上面的跳转块完全分离。两者不能合并,否则跳转会失效或陷入循环。
- 必须写
listen 443 ssl http2;(http2可选但强烈建议) -
ssl_certificate和ssl_certificate_key路径要绝对准确,文件权限需为600(尤其私钥) - 建议加上安全头:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;,让浏览器记住只走 HTTPS
验证与生效不能跳过
改完配置不是保存就完事,Nginx 不会自动重载——必须人工确认并触发。
- 先执行
sudo nginx -t:检查语法是否合法、路径是否存在、证书能否读取 - 成功后运行
sudo systemctl reload nginx(或sudo nginx -s reload) - 测试时直接访问
http://yourdomain.com/some-path?x=1,应秒跳https://...,状态码是 301,地址栏显示锁图标
避开常见坑点
很多跳转失败不是配置写错了,而是环境没对齐。
- 云服务器或防火墙(如 ufw、iptables)必须放行 443 端口,否则跳过去也打不开
- 别用
rewrite替代return:前者多一层正则解析,易出变量错误;return 301是原子操作,更安全、更快 - 如果用了 CDN(如 Cloudflare),注意它的“强制 HTTPS”开关。若 CDN 已处理跳转,源站 Nginx 就只需监听 443;若源站也要跳,则 CDN 应关闭该功能,避免双重跳转导致 301→301→301











