最高效可靠的方式是用独立server块实现HTTP到HTTPS的301跳转:80端口块仅含listen 80、server_name和return 301 https://$host$request_uri;443端口块独立配置ssl证书、HSTS及业务逻辑,二者完全解耦。

直接在 Nginx 中用独立的 server 块实现 HTTP 到 HTTPS 的 301 跳转,是最高效、最可靠的方式。关键不是写得复杂,而是结构清晰、端口分离、指令精准。
只监听 80 端口的跳转 server 块
这个块专用于接收所有 HTTP 请求,并立即返回 301 响应,不处理任何页面内容:
- 必须包含
listen 80;,不能加ssl或证书相关指令 - 使用
return 301 https://$host$request_uri;——$host保留原始域名(含 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;,增强安全性 - 这个块里可以正常配置 PHP、静态文件、反向代理等业务逻辑,与跳转块完全解耦
配置后务必验证并重载
写完别急着测试网页,先确保 Nginx 能正确加载新规则:
- 运行
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 端口,否则 HTTPS 根本无法响应,跳转后会卡住或超时
- 证书私钥文件(privkey.pem)权限不能是 644,Nginx 默认以 nobody 或 www-data 用户读取,需设为
chmod 600 - 不要用
rewrite替代return,rewrite ... redirect是 302,rewrite ... permanent才是 301,但不如return 301直接、轻量、无变量解析风险 - 如果用了 CDN(如 Cloudflare),要确认源站 Nginx 是否仍需跳转——若 CDN 已开启“强制 HTTPS”,源站再跳转可能造成双重 301,反而影响性能

















