Nginx 1.22.1仅将非www域名重定向至www,保留子域名
Nginx配置:仅将example.com重定向至www.example.com,子域名保留原域名与协议
问题根源
你的配置问题出在默认server匹配和监听端口的混合配置上:
- 第二个server块同时监听80和443端口,当子域名的HTTPS请求没有对应server块时,会被Nginx当作默认server匹配到这个块,导致子域名被错误重定向。
- 使用
www.$host会给子域名添加www前缀(比如es.example.com变成www.es.example.com),而硬编码www.example.com则会把所有匹配到该server块的请求都导向主域名的www版本。
正确配置方案
以下是符合需求的完整Nginx配置,拆分不同场景的server块,确保匹配逻辑精准:
# 1. 处理HTTP端口(80)的 example.com 请求,直接重定向到HTTPS的www版本 server { listen 80; listen [::]:80; server_name example.com; return 301 https://www.example.com$request_uri; } # 2. 处理HTTP端口(80)的所有子域名请求,重定向到对应子域名的HTTPS版本(若需保留HTTP可删除此块) server { listen 80; listen [::]:80; server_name *.example.com; return 301 https://$host$request_uri; } # 3. 处理HTTPS端口(443)的 example.com 请求,重定向到HTTPS的www版本 server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/key.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/ca.pem; ssl_stapling_verify on; return 301 https://www.example.com$request_uri; } # 4. 主站点:处理www.example.com的所有请求 server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/key.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/ca.pem; ssl_stapling_verify on; access_log /var/log/nginx/example.com.access.log rt_cache; error_log /var/log/nginx/example.com.error.log; root /var/www/example.com/htdocs; index index.php index.html index.htm; include ... # 保留原有配置片段 }
配置说明
- 精准匹配example.com:将HTTP和HTTPS的
example.com请求拆分到独立server块,直接重定向到https://www.example.com$request_uri,确保只有主域名的非www版本被重定向。 - 子域名独立处理:子域名的HTTP请求会被导向对应子域名的HTTPS(若不需要HTTPS可删除第二个server块),而HTTPS的子域名请求如果没有单独配置server块,Nginx不会将其匹配到主域名的重定向块(因为主域名的HTTPS块只匹配
example.com)。 - 避免默认server干扰:每个server块都明确指定
server_name,Nginx只会根据精确匹配规则处理请求,不会将子域名误匹配到主域名的重定向逻辑。
内容的提问来源于stack exchange,提问作者Jasom Dotnet
相关产品推荐
相关产品推荐

