nginx www 跳转非www 301:canonical 冲突与验证文件 301 失败的两个坑
背景
站点此前让 www.weiserv.com 和 weiserv.com 同时服务同一内容,存在 SEO 重复内容风险,且与页面 canonical 标签(指向非 www)不一致。需要在 nginx 层做 www 跳转非www 的 301 归一。
一、现象:两个域名服务同一内容
- 浏览器访问
www.weiserv.com和weiserv.com都返回同样的页面; - 百度站长平台的规范 URL(canonical)指向非 www,但 www 仍可访问,两者不一致;
- 若直接改,已通过的百度站点验证可能复检失败。
二、根因:跳转目标用了 $host、验证通道被 301 误伤
改前的两个失误:
# 改前::80 跳转保留 www($host 会保留用户输入的 www)
server { listen 80; server_name weiserv.com www.weiserv.com;
return 301 https://$host$request_uri; } # $host 含 www → 永远跳回 www
# 改前::443 单块同时服务两个域名
server { listen 443 ssl; server_name weiserv.com www.weiserv.com;
location /baidu_verify_ { root /path/to/staticfiles; } ... }
:80用https://$host会原样保留 www,www 跳转非www 根本没生效;- 把重定向铺到
server级后,location /baidu_verify_也会被 301 覆盖——百度验证器拒收 301,已通过的验证会在复检时突然失败。
三、解决:目标写死 + nginx 双 443 重定向块都保留验证通道
# /etc/nginx/sites-enabled/weiserv
# 1) :80 —— 目标写死非 www,HTTP→HTTPS 一步到位
server {
listen 80;
server_name weiserv.com www.weiserv.com;
location /baidu_verify_ { root /path/to/staticfiles; }
location / { return 301 https://weiserv.com$request_uri; }
}
# 2) 新增 :443 www 重定向块
server {
listen 443 ssl;
server_name www.weiserv.com;
include /etc/nginx/ssl_options.conf;
return 301 https://weiserv.com$request_uri;
}
# 3) 原 :443 块 server_name 收窄为仅 weiserv.com(保留 baidu_verify 与 bdunion.txt 200)
server {
listen 443 ssl default_server;
server_name weiserv.com;
location /baidu_verify_ { root /path/to/staticfiles; }
# bdunion.txt 等价简化:真实为 alias 直出文件(http 下随全站 301→https),此处 return 200 语义等价
location = /bdunion.txt { return 200; }
# ... 原有站点配置
}
改前务必备份,再校验重载:
sudo cp /etc/nginx/sites-enabled/weiserv /var/backups/weiserv.vhost.bak.$(date +%Y%m%d%H%M)
sudo nginx -t && sudo nginx -s reload
四、验证:curl 实测 301 与 200
# www 全部 301 到非 www(nginx www 301 归一生效)
$ curl -sI https://www.weiserv.com/ | grep -iE '^HTTP|^location'
HTTP/1.1 301 Moved Permanently
Location: https://weiserv.com/
# 规范域名仍 200,canonical 一致
$ curl -s -o /dev/null -w '%{http_code}' https://weiserv.com/
200
# baidu_verify_ 文件在 http/https × www/非www 四组合仍 200(真实文件名带 codeva- 前缀,
# 如 baidu_verify_codeva-XXXX.html;未被 301 误伤)
# 注:bdunion.txt 在 https 下 200,http 下随全站 301→https(设计使然),勿与 baidu_verify_ 的四组合 200 混淆
$ curl -s -o /dev/null -w '%{http_code}' https://www.weiserv.com/baidu_verify_codeva-XXXX.html
200
五、避坑清单
:80的跳转目标必须写死域名,别用$host——$host会原样保留用户输入的 www,归一形同虚设。- 百度验证器拒收 301:任何重定向改动都要保留
location /baidu_verify_(以及bdunion.txt)直出 200,否则已通过验证会复检失败。 - 双
:443块都要保留验证通道:nginx 双 443 重定向(www 块 + 非 www 块),只要服务了含验证文件的域名,就得放行。 - 改前先备份 +
nginx -t校验:配置错了会全站 502,备份能秒回滚。
广告位占位 · post-inline