Nginx 如何去掉 www 并同时跳转到 HTTPS?

Nginx 一步完成"去 www + 强制 HTTPS":www 的 80/443 两个 server 块都 301 到 https://裸域;附四种入口组合表、证书要求(覆盖 www 与裸域)与 FAQ。

最佳实践
Nginx 如何去掉 www 并同时跳转到 HTTPS?封面

四个入口(http/https × www/裸域)都要照顾:www 变体无论 80 还是 443 都 return 301 https://裸域$request_uri;裸域 80 跳 443;只有裸域 443 真正提供服务。

完整配置

# ① http + www → https 裸域
server {
    listen 80;
    server_name www.example.com;
    return 301 https://example.com$request_uri;
}

# ② http + 裸域 → https 裸域
server {
    listen 80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}

# ③ https + www → https 裸域(证书要先握手成功!)
server {
    listen 443 ssl;
    server_name www.example.com;
    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    return 301 https://example.com$request_uri;
}

# ④ https + 裸域:真正干活的 server 块
server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    root /var/www/site;
    index index.html;
    location / { try_files $uri $uri/ =404; }
}

两个最容易漏的点

  1. ③ 不能省:用户直接敲 https://www.example.com 时,HTTPS 握手发生在跳转之前——没有 ③,用户先看到证书错误或另一个站点的内容。而且证书必须同时覆盖 www.example.comexample.com(一张证书两个 SAN),否则握手阶段就失败,跳转根本没机会执行。
  2. 合并写法可行但要小心server_name www.example.com example.com; if ($host = www.example.com) {...} 这种写法引入 if 嵌套,Nginx 社区共识是 server 块拆分更清晰,别省这几个块。

申请双名证书:

certbot --nginx -d example.com -d www.example.com

验证四路跳转

curl -I http://www.example.com/path?q=1    # → https://example.com/path?q=1
curl -I http://example.com/path?q=1        # → https://example.com/path?q=1
curl -I https://www.example.com/path?q=1   # → https://example.com/path?q=1
curl -I https://example.com/path?q=1       # → 200

四条链各跳一次就到终点,无循环、无多跳。

观测云对照

四类入口的流量结构是检验跳转配置的最佳数据:把访问日志接入观测云,按 host × 状态码聚合——健康状态下 www 与 http 裸域上应只有 301,全部 200 集中在 https 裸域;哪个入口还有 200 流量,说明对应 server 块没配对。跳转异常、证书即将过期都可以通过监控器告警。

常见问题(FAQ)

Q:反过来要 www、跳裸域,怎么改?
A:逻辑完全对称:把 server_name 里的角色互换——裸域的块 301 到 https://www.example.com$request_uri,www 的 443 块做正式服务。

Q:多次跳转(http www → https www → https 裸域)有影响吗?
A:有。每多一跳多一次往返延迟,搜索引擎也不喜欢跳转链。上面的配置保证任意入口最多一跳到终点。

Q:HSTS 要不要一起上?
A:稳定运行 HTTPS 一段时间后再加 add_header Strict-Transport-Security "max-age=31536000" always;,加在 ④ 里。注意 HSTS 只记在浏览器侧,配错了要等缓存过期。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台