做站点时间久了你会发现一个很邪门的现象明明是同一个网站在搜索引擎里却能搜出两个地址http://www.domain.com和http://domain.com各占一条站内文章也被人分头引用。这不是域名解析坏了而是典型的 URL 不规范问题。要解决它核心就是做一次 301 重定向把 http://www.domain.com 的访问统一导向 http://domain.com。这篇内容适合正准备上线的个人站长也适合接手老项目的运维。不管你是要清理历史遗留的重复入口还是想在新站点上线第一天就把规范做好都可以按下面的思路走一遍。我会先把“选哪个域名”的账算清楚再讲跳转背后的 HTTP 原理然后给出 Nginx、Apache、IIS 三种主流环境的完整配置最后说验证方法和上线后的收尾清单。1. 先站队www 和裸域名到底哪一个才是你的归宿很多教程上来就甩配置但我建议你先想清楚方向。方向错了后面的 301 就是白干甚至会把权重从一个坑挪到另一个坑。1.1 两种地址在浏览器和服务器的眼里完全不同从普通用户的角度看http://www.domain.com和http://domain.com无非差了几个字母。但在浏览器、服务器和搜索引擎眼里这是两个不同的主机名意味着两套完全独立的资源入口。先说 Cookie。如果你不显式设置Domaindomain.com浏览器会按请求的主机名分别存储 Cookie。用户从www.domain.com登录跳到domain.com之后登录态就丢了需要重新登录。这在高并发站点上尤其烦人用户以为是系统出 bug实际上是跨子域 Cookie 没打通。再说静态资源和 CDN。很多 CDN 厂商支持泛解析裸域名比www子域更容易做分发配置反过来也有不少团队习惯把www作为一个稳定的子域单独接 WAF、单独配缓存方便和主站解耦。最关键的还是 SEO。搜索引擎对“主机名”是敏感的www和非www会被当成两个站点分别收录。外链一部分指向www一部分指向裸域名权重就散了。这也是为什么会出现“正式站点收录少、多出来的镜像页面反而排在前面”的怪事。1.2 不同体量站点的选型建议选哪个没有绝对标准但我给你一个判断模型个人博客、SaaS 后台、API 服务、工具类站点优先裸域名。理由很简单输入短、配置少、后续用 CDN 泛解析也省事而且内部逻辑里不需要再区分“主站”和“WWW 子域”。企业官网、电商、会员体系复杂的站点优先www。www是一个稳定的子域可以单独做缓存策略也可以只给它配严格的鉴权而裸域名负责跳转。很多企业邮箱、SSL 证书的历史配置也围绕www展开迁移成本更低。如果团队没有明确偏好我建议按“用户输入成本最低”的原则来面向大众的内容站裸域名更友好需要给子域预留扩展空间的业务系统www更稳妥。一旦选定就用 301 把另一个地址永久甩掉。别今天跳 www明天跳裸域名搜索引擎被反复折腾之后会花很长时间重新评估你的站点权重。2. 跳转的底牌301状态码、Location和URL规范化配置本身不难难的是理解为什么 301 才是唯一正解。很多人图省事用了 302结果几个月后权重依然没转过去。2.1 301和其他状态码的差异先看一张表记住每个状态码的作用状态码含义是否保留请求方法对SEO的影响301 Moved Permanently永久移动通常会变成GET权重转移浏览器和搜索引擎都会缓存结果302 Found临时移动通常会变成GET权重不转移只当作临时跳转307 Temporary Redirect临时重定向保留POST等方法权重不转移适合表单场景308 Permanent Redirect永久重定向保留POST等方法权重转移但兼容性不如301站点换主域名、统一 www 入口、清理重复页面这些都是永久性操作所以必须用 301。304 这种“Not Modified”完全是另一个场景千万别混在一起。用 302 的典型后果是搜索引擎会认为你只是临时把用户指引到别处排名权重还挂在老地址上过段时间又继续抓取老 URL甚至出现新旧两版同时被收录的情况。我见过不止一个团队因为把 redirect 写成 302导致流量迟迟没有迁移到 HTTPS 新站最后只能全量返工。2.2 一个重定向响应背后的真实流程当用户访问http://www.domain.com/abc时服务器返回的完整响应大致长这样HTTP/1.1 301 Moved Permanently Location: http://domain.com/abc Content-Type: text/html Content-Length: 0浏览器和搜索引擎爬虫看到Location字段就会发起第二次请求去访问http://domain.com/abc。用户感知到的是一次短暂跳转但对爬虫来说这是一次“旧地址作废新地址接收全部信号”的声明。这里有两个细节要注意。第一Location必须写完整不能只写/abc否则浏览器不知道要去哪个主机名。第二响应里不要放太多 HTML 内容301 的正文通常留空省流量也避免被误解析。2.3 Canonical标签是第二道保险服务器层面的 301 是最可靠的但站点里难免有历史页面、第三方接口、临时活动页没走重定向规则。此时relcanonical能兜底。在页面head里加上link relcanonical hrefhttp://domain.com/文章路径 /意思是告诉搜索引擎这个页面即使被访问了真正的规范地址也是指向裸域名那个。配合服务器 301双保险的效果最稳。但要注意canonical 是“建议”搜索引擎有权利不采纳而 301 是“命令”。所以 canonical 永远只能作为辅助不能替代真正重定向。3. 三种主流服务器配置把www地址稳准狠地甩回主域现在进入实操环节。我会按 Nginx、Apache、IIS 三种情况分别给配置并说明为什么这么写。3.1 Nginx两个server块比if判断干净得多Nginx 下最常见的写法是给www.domain.com单独建一个 server 块只干一件事返回 301。server { listen 80; server_name www.domain.com; return 301 http://domain.com$request_uri; } server { listen 80; server_name domain.com; root /var/www/domain; index index.html; location / { try_files $uri $uri/ 404; } }这段配置的核心是$request_uri。它是一个内置变量保存了用户请求的完整路径和查询参数比如/article?id1。把它拼到目标域名后面就能保证从www.domain.com/article?id1跳转到domain.com/article?id1路径、参数都不丢。为什么不推荐在同一个 server 块里写if ($host www.domain.com)因为 Nginx 的if是 rewrite 模块里的“黑魔法”指令执行顺序和直觉不一致容易引发莫名其妙的 500、404。独立 server 块的写法逻辑清晰也方便以后单独给www加 HSTS 或访问日志维护成本最低。如果以后要换成“裸域名跳转到 www”只需把两个 server 块里的域名对调逻辑一模一样。3.2 ApacheVirtualHost和.htaccess两条路Apache 环境优先在 VirtualHost 里配置。找到www.domain.com对应的站点配置VirtualHost *:80 ServerName www.domain.com Redirect 301 / http://domain.com/ /VirtualHostRedirect 301 / http://domain.com/的意思是把当前虚拟主机下所有路径301 到http://domain.com/下对应路径。Apache 会自动把/article?id1拼接过去不需要额外变量。如果你只有 .htaccess 的修改权限比如虚拟主机面板环境可以使用 mod_rewriteRewriteEngine On RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC] RewriteRule ^(.*)$ http://domain.com/$1 [L,R301]这里判断的是HTTP_HOST而不是SERVER_NAME。原因是SERVER_NAME在部分 Apache 配置里可能被ServerAlias或默认虚拟主机覆盖导致判断结果不准确HTTP_HOST直接取自请求头最接近用户真实访问的地址。[NC]表示大小写不敏感[L,R301]表示这是最终规则并返回 301。3.3 IISURL Rewrite的web.config写法Windows 服务器上用 IIS 的话首先要安装 URL Rewrite 模块。安装完成后可以直接在站点根目录的web.config里加规则rewrite rules rule nameRemove WWW stopProcessingtrue match url(.*) / conditions add input{HTTP_HOST} pattern^www\.domain\.com$ / /conditions action typeRedirect urlhttp://domain.com/{R:1} redirectTypePermanent / /rule /rules /rewrite关键点有两个。第一个是add input{HTTP_HOST} pattern^www\.domain\.com$ /它只匹配以www.domain.com为开头的请求不会误伤其他子域。第二个是action typeRedirect redirectTypePermanent /Permanent对应 HTTP 301千万别选Found那是 302。如果服务器上同一个站点绑定了一堆域名只想对其中一个做跳转stopProcessingtrue可以保证这条规则匹配后直接结束不再执行后续规则。3.4 不得已时的兜底面板转发和前端跳转有些托管面板提供“域名转发”功能原理多半是 meta refresh 或 iframe不推荐用在正式站点。meta refresh 虽然能跳但搜索引擎会把它当成一种弱信号权重继承效果远不如 301。如果连服务器配置都改不了只能临时用 JavaScript 跳转script if (window.location.host www.domain.com) { window.location.replace(http://domain.com window.location.pathname window.location.search); } /script这段代码我强调过很多次是“最后手段”。爬虫可能不执行 JS用户也可能在脚本加载前就关闭页面用它做长期方案必然出问题。4. 动手之前必须打理好的两个前置条件DNS和HTTPS服务器跳转规则写得再好DNS 和证书没做好照样会翻车。这一节说的是配置之前最容易踩的两个坑。4.1 解析记录A记录与CNAME的搭配方式你要让两个域名都能被访问解析记录至少得这样配主机记录记录类型记录值说明domain.comA服务器IP裸域名指向服务器wwwCNAMEdomain.comwww 指向裸域名这里有个常见误区很多人把www的 CNAME 指向裸域名后就觉得“反正都会到同一台服务器”。确实在服务器层面两个域名解析到同一入口但这只是第一步服务器还必须知道要把www的请求跳过去。DNS 只负责解析不负责301这是两层完全不同的逻辑。另外要注意根域名本身不能设置 CNAME这是 DNS 协议的限制。如果服务商支持 ALIAS 或 ANAME 记录可以例外但大多数情况下裸域名直接用 A 记录最稳妥。如果以后服务器迁移 IP只需要改裸域名的 A 记录www的 CNAME 会自动跟随。4.2 HTTPS下的重定向链路先证书后跳转现在做站点基本上绕不开 HTTPS。如果你既跳转域名又跳协议整个过程会变成http://www.domain.com先跳到http://domain.com再通过另一条规则跳到https://domain.com。白白多一跳用户体验和爬虫效率都会受影响。更稳妥的做法是合并成一条链路从http://www.domain.com直接 301 到https://domain.com。为此证书必须同时覆盖www.domain.com和domain.com。有一种典型坑是只申请了*.domain.com通配符证书然后发现通配符不匹配裸域名https://domain.com打开就是证书错误。Nginx 下推荐这样拆# 所有80端口请求统一跳到HTTPS的裸域名 server { listen 80; server_name www.domain.com domain.com; return 301 https://domain.com$request_uri; } # www的443端口只做跳转 server { listen 443 ssl; server_name www.domain.com; ssl_certificate /path/domain.pem; ssl_certificate_key /path/domain.key; return 301 https://domain.com$request_uri; } # 真正的网站本体 server { listen 443 ssl; server_name domain.com; ssl_certificate /path/domain.pem; ssl_certificate_key /path/domain.key; root /var/www/domain; index index.html; }这里最容易被忽略的是www的 443 server 块也要配置正确的证书否则用户直接输入https://www.domain.com时TLS 握手阶段就会告警根本没机会执行后面的 301。证书文件用同一个包含 SAN 的证书即可。4.3 本地hosts模拟测试环境改线上配置之前先在本地模拟解析环境可以省去很多来回折腾。操作方法很简单Linux/macOS 编辑/etc/hostsWindows 编辑C:\Windows\System32\drivers\etc\hosts加入两行127.0.0.1 www.domain.com 127.0.0.1 domain.com修改之后本地访问这两个域名都会指向本机。这样你可以在不迁移线上、不修改公网 DNS 的情况下把完整的跳转链路验证一遍。测试完记得删掉这两行否则会一直干扰本地开发。5. 上线验证与排错别让重定向在你看不见的地方翻车配置写完不等于工作做完。我见过太多“配置看起来没问题但线上就是跳不对”的案例所以专门留一节讲验证和排错。5.1 curl三板斧状态码、Location、整条链路第一板斧看单次跳转的状态码和 Locationcurl -s -o /dev/null -w status:%{http_code}\nlocation:%{redirect_url}\n http://www.domain.com预期输出是status:301 location:http://domain.com/如果你看到 200说明服务器根本没执行跳转看到 302说明规则写错了状态码。第二板斧测试路径和参数是否保留curl -s -o /dev/null -w status:%{http_code}\nlocation:%{redirect_url}\n http://www.domain.com/article?id123预期location应该是http://domain.com/article?id123。如果跳过去变成了http://domain.com/说明配置里用了不带路径的跳转目标要回头检查是不是漏了$request_uri或$1。第三板斧用-L跟随整条链路curl -sIL http://www.domain.com这条命令会一路跟到最终页面适合检查有没有多余的中间跳。正常应该是301到裸域名再返回200。如果看到两次 301就要检查是不是 http 跳 https、https 又跳回 http形成了隐形绕路。5.2 浏览器和第三方工具的检查视角浏览器 F12 的 Network 面板是最直观的验证方式。打开开发者工具勾选 Preserve log然后访问http://www.domain.com观察第一个请求状态码是 301说明跳转规则生效Headers 里的 Location 指向http://domain.com/说明跳转目标正确请求链表里只有一次 301 一次 200说明链路干净。如果浏览器直接显示“重定向次数过多”基本就是循环了。还有一种情况是 HSTS 已开启浏览器会先把http://www自动升级成https://www再发给服务器导致你在浏览器的 Network 面板里看不到最初的 80 端口 301。此时用 curl 测试最准确因为 curl 不受 HSTS 策略影响。5.3 高频故障循环、丢路径、丢参数、HTTPS混合内容我整理了实际操作里最常见的问题对照着排查会快很多故障现象可能原因解决办法重定向循环规则A跳到BB的规则又跳回A逐个 server 块检查server_name和跳转目标是否冲突跳到首页路径丢失用了固定/而不是$request_uri或$1改成保留路径的变量写法查询参数丢失重定向目标带了?但没拼接 query用$request_uri或在 Apache 里加QSA标志页面出现“不安全内容”提示站内图片、脚本仍用 http 绝对地址全局搜索替换为 https 或相对协议地址跳转目标证书错误证书没有覆盖目标域名申请包含 SAN 的证书同时覆盖 www 和裸域名排查循环时有一个土办法把跳转链路的每一步写成日志。Nginx 可以在www的 server 块里开独立 access log看到底是哪个请求被反复跳。大多数循环问题出在“http 和 https 的 server_name 互相打架”比如 http 的规则跳 https 的裸域名而 https 的裸域名又有一条规则跳回 http。6. 跳转之后的收尾内链、后台和观察期服务器 301 上线只是开胃菜后面的收尾工作决定这次规范化能走多远。6.1 把站内所有绝对地址换成统一入口很多人以为服务器做了 301站内链接就可以继续乱写。实际上如果某个页面的源码里还带着http://www.domain.com/xxx用户点击时会先产生一次额外跳转白白增加延迟搜索引擎抓取也会多绕一跳。上线后要清理的东西包括数据库文章内容里的历史绝对链接主题模板里写死的site_url或图片地址robots.txt里的Sitemap地址提交过的sitemap.xml中所有 URL。建议在程序代码层面对外输出链接时统一使用一个“站点主域”常量后续要改域名只改一处。这也是为什么很多框架推荐用相对路径或协议相对路径//domain.com/xxx能少踩很多坑。6.2 站长工具和统计平台的同步设置重定向完成后需要到各平台申报变更否则搜索引擎需要更长的时间来消化Google Search Console添加裸域名和 www 两个版本使用“地址更改”工具把 www 的属性指向裸域名。百度搜索资源平台提交站点改版规则按照平台要求填写源地址和目标地址。统计工具确认默认域名是裸域名否则后续 PV、UV 数据会劈成两份。第三方统计检查历史报表里 iframe 嵌的是哪个地址统一替换。这些操作不是可选项。搜索引擎抓取有一个“信任周期”主动申报能大幅缩短权重转移的等待时间。6.3 观察节奏与回退预案我一般用三个时间窗口观察第 1~3 天盯访问日志里的 404、500重点看是不是有历史外链带着老路径过来被跳转规则错误地丢弃了。第 1~2 周看站长平台的抓取异常、索引变化此时旧地址的收录量应该开始下降新地址的索引量逐步上升。第 1 个月以上看核心关键词排名和自然流量曲线。理论上前两周会有小幅波动这是正常现象。如果真出现必须回退的情况比如业务上高层突然要求保留 www 作为主入口不要慌。把前面配置里的目标域名整体对调同时重新提交站长工具的改版规则即可。但我必须提醒一句反复横跳对权重伤害极大每次改版都意味着重新积累信任没必要就别玩这个。我自己的习惯是在切换前一天把所有配置在测试环境完整执行一遍然后列一个 curl 测试清单首页、带路径页面、带参数页面、HTTPS 入口逐个跑一遍再正式上线。这个小习惯帮我避开过好几次线上跳转事故也推荐你试试。