结论先行:两条 server 块搞定跳转
给站点装上 HTTPS 证书后,最该做的一步就是让所有 http 请求自动跳到 https,否则用户手动输域名、老外链、搜索引擎收录的 http 地址都会停在明文页面。Nginx 里实现这件事非常简单:保留一个监听 80 端口的 server 块,用 301 永久重定向把请求甩到 https 即可,不需要装任何模块。
下面从证书已就绪的状态开始,假设你的域名是 example.com,证书文件放在 /etc/nginx/ssl/ 下。
第一步:确认 HTTPS 站点本身能正常访问
先别急着做跳转,确认 443 的 server 块已经跑通。一个最小可用的 HTTPS 配置长这样:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example;
index index.html index.php;
}
改完执行 nginx -t 检查语法,通过后 nginx -s reload。浏览器访问 https://example.com 能正常打开,再继续下一步。
第二步:新增 80 端口跳转 server 块
在同一个配置文件里(或 conf.d 下新建一个 .conf),加一个只负责跳转的 server 块:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
这里三个要点:
listen 80;负责接住所有 http 请求。$host会保留用户访问的域名,带 www 的跳 www,不带的跳裸域,避免跳错。$request_uri保留原始路径和查询参数,比如 /a/b?id=1 会原样带到 https 上,不会丢参数。
保存后同样 nginx -t 再 nginx -s reload。
第三步:验证跳转是否生效
用 curl 看响应头最直接:
curl -I http://example.com
预期看到:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
如果带路径测试:
curl -I http://example.com/blog/post?id=5
Location 应该完整保留 /blog/post?id=5。浏览器里再手动输一次 http 地址,确认地址栏自动变成 https 且没有证书告警。
常见坑与补充说明
- 用 301 还是 302:确定永久启用 HTTPS 就用 301,搜索引擎会把权重转移到 https;只是临时测试用 302。
- 别把跳转写进 443 的 server 块:跳转逻辑必须放在监听 80 的块里,否则 https 请求也会被自己重定向,形成死循环。
- HSTS 可选加强:在 443 的 server 块里加
add_header Strict-Transport-Security "max-age=31536000" always;,让浏览器以后强制走 https。但一旦开启,短期内无法回退,建议先确认全站 https 无混合内容再上。 - CDN 场景:如果前面套了 CDN,回源到 Nginx 的请求可能已经是 http,需要确认 CDN 侧也开启了 https 跳转,否则用户侧仍可能看到 http。
整套配置就这么多,核心就是那个 return 301 https://$host$request_uri;。改完记得 reload,然后拿 curl 或浏览器实测一遍,别只看配置文件就以为完事了。


