Nginx 如何把所有 HTTP 请求跳转到 HTTPS 且保留子域名?

Nginx 全站 HTTP 跳 HTTPS 且保留子域名:server_name 用通配或正则捕获 + return 301,$host 变量自动保留主机名;含完整配置、HSTS 提示与 FAQ。

最佳实践
Nginx 如何把所有 HTTP 请求跳转到 HTTPS 且保留子域名?封面

$host 变量做跳转目标:它自动带上请求里的原始主机名(含子域名),一条规则覆盖所有子域。

server {
    listen 80;
    server_name *.example.com example.com;

    return 301 https://$host$request_uri;
}

$host 保留子域名(api.example.comhttps://api.example.com/...),$request_uri 保留完整路径和查询串。

各子域配置分散时的通用写法

如果你的 80 端口配置分散在多个文件里、不想逐个加跳转,可以用一个"通吃"的默认 server:

# 放在 include 顺序最前(如 00-redirect.conf),成为 80 端口默认 server
server {
    listen 80 default_server;
    server_name _;                    # 匹配一切 Host

    return 301 https://$host$request_uri;
}

之后所有 80 端口进来的请求——无论哪个子域——统一跳到对应的 HTTPS 地址。

HTTPS 侧正常配

server {
    listen 443 ssl;
    server_name api.example.com;
    ssl_certificate     /etc/nginx/ssl/example.com-wildcard.crt;   # 泛域名证书
    ssl_certificate_key /etc/nginx/ssl/example.com-wildcard.key;
    ...
}

多子域通常配一张泛域名证书*.example.com),一份配置给所有子域复用。

可选:跳转后加 HSTS

确认 HTTPS 稳定运行后,在 443 的 server 块里加:

add_header Strict-Transport-Security "max-age=31536000" always;

浏览器此后一年内直接走 HTTPS,连 301 跳转都省了。⚠️ 没把握前别把 max-age 设大——设错了得等缓存过期才能回退。

观测云对照

跳转链是流量入口的第一环:配错了用户看到的是"网站打不开"。把 Nginx 访问日志接入观测云,301/302 与 200 的比例、跳转后是否二次跳转(https→http→https 循环)都能从日志里分析出来;用站点可用性监测直接探测各子域的 HTTPS 端点,证书过期或跳转异常分钟级告警。

常见问题(FAQ)

Q:$host 和 $server_name 有区别吗?
A:有。$host 取自请求的 Host 头(客户端实际访问的域名);$server_name 是配置里写的第一个名字。保留子域名的场景必须用 $host

Q:跳转后 POST 表单数据会丢吗?
A:301/302 跳转后浏览器会把 POST 变 GET,数据丢失。必须保证表单 action 直接写 https 地址,跳转只是兜底;API 场景考虑 307/308(保持方法)。

Q:certbot 装的跳转配置为什么长得不一样?
A:certbot 用 if ($host = ...) { return 301 ... } 的写法,效果相同。return 写在 server 块顶层(上面示例)更简洁高效。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台