You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Nginx非WWW转WWW配置异常:浏览器反向跳转、Curl返回200

问题原因分析及解决方案

咱们先拆解你的配置和现象里的矛盾点,一步步找到问题根源:

1. Nginx HTTP 配置的顺序逻辑错误

你的HTTP部分有两个server块,但第一个listen 80 default_server的块会拦截所有80端口的请求(不管域名是example.com还是www.example.com),直接跳转到https://$host$request_uri。这就导致第二个server_name example.com的块完全不会被触发——所有HTTP请求都走了第一个默认server,所以http://example.com只会被跳转到https://example.com,而不是你期望的https://www.example.com

2. HTTPS 缺少example.com的专属处理块

你的HTTPS配置只有server_name www.example.com的代理块,没有针对example.comHTTPS请求的规则。当用户访问https://example.com时,Nginx找不到匹配的server块,就会自动用第一个监听443端口的server块(也就是www的那个)来处理请求,直接把流量转发给Node应用。

这时候curl请求会返回200(因为curl默认不缓存重定向),但浏览器可能缓存了之前的301重定向规则(比如你之前可能配置过www→非www的永久重定向,而301会被浏览器强制缓存),就出现了浏览器反向跳转的异常。

3. 浏览器缓存的301重定向是直接诱因

301永久重定向的缓存优先级很高,哪怕你现在改了Nginx配置,浏览器依然会沿用旧的重定向逻辑。这就是为什么终端curl请求显示正常,但浏览器访问时出现反向跳转的核心原因。


修复步骤

第一步:修正HTTP重定向配置

把HTTP部分的两个server块合并,确保所有HTTP请求直接跳转到HTTPS的www域名:

# HTTP — redirect all traffic to HTTPS WWW
server {
 listen 80;
 listen [::]:80 default_server ipv6only=on;
 server_name example.com www.example.com;
 return 301 https://www.example.com$request_uri;
}

第二步:添加HTTPS的example.com重定向块

在现有HTTPS代理块之前,添加专门处理example.comHTTPS请求的规则:

# HTTPS — redirect non-WWW to WWW
server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 server_name example.com;

 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
 ssl_dhparam /etc/ssl/certs/dhparam.pem;
 # include snippets/ssl-params.conf;

 return 301 https://www.example.com$request_uri;
}

# 原有的HTTPS代理server块保持不变
server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 server_name www.example.com;
 # ... 其余代理配置不变
}

第三步:规避浏览器缓存干扰

修改配置后,需要:

  • 清除浏览器的缓存(重点清除缓存的重定向规则)
  • 或者直接用隐私/无痕模式访问,避免旧缓存影响测试

第四步:重启Nginx生效

执行命令让新配置生效:

sudo systemctl restart nginx

这样配置后,所有HTTP/HTTPS的非www请求都会被正确跳转到www,同时解决了浏览器缓存导致的异常问题。

内容的提问来源于stack exchange,提问作者lightbringer

火山引擎 最新活动