301重定向必须在服务器层(如Nginx、Apache或PHP header)配置,不能用HTML的meta refresh或JavaScript跳转;前者返回真实301状态码,确保浏览器显示新URL、搜索引擎识别为永久迁移并传递权重,后者返回200,不被当作永久跳转。

301重定向必须在服务器层配置,不能写在HTML里
浏览器地址栏显示新URL、搜索引擎识别为永久迁移、权重能有效传递——这三件事只在真实返回 301 状态码时才成立。用 <meta http-equiv="refresh"> 或 JavaScript 跳转,服务器实际返回的是 200 OK,爬虫根本不会当真。
常见错误包括:
- 在 WordPress 主题的
header.php里用header('Location: ...', TRUE, 301)—— 一旦前面有空白、<html>或 echo 输出,就会触发headers already sent错误 - 只对 PHP 页面做跳转,漏掉
.js、.css、API 接口、静态 HTML 文件等非 PHP 路径 - 用 Apache 的
RedirectMatch写错正则,导致部分旧路径没覆盖,或意外匹配到不该跳的资源
Nginx 推荐写法:return 301 https://example.com/new-path$request_uri;;Apache 推荐用 RewriteRule 而非 Redirect,便于控制路径匹配精度。
canonical 标签 href 必须指向新 URL,不管页面是否还能访问
<link rel="canonical"> 不是“我从哪来”,而是“你该记谁”。哪怕旧 URL 已被 301 跳走,只要它还能被直接打开(比如缓存未清、跳转配置遗漏),它的 <head> 里也得写上新地址的 canonical。
立即学习“前端免费学习笔记(深入)”;
典型反例:
- 旧页
https://old.com/article/123301 跳到https://new.com/blog/ai-tools,但旧页 HTML 里 canonical 还写着自己——这等于告诉搜索引擎:“别信跳转,我才是正版” - 新页 canonical 指向带参数的 URL,如
https://new.com/blog/ai-tools?ref=seo,导致参数变体再次产生重复内容
正确做法:所有涉及改版的页面,canonical 的 href 值统一为语义上最终、干净、无参数的新 URL(协议、域名、路径全写死,不带 ? 后面的部分)。
301 和 canonical 不是二选一,而是分层协作
301 解决的是“用户和爬虫找不着门”的问题;canonical 解决的是“门开着,但里面好几扇一模一样的门”的问题。即使 301 配置完美,以下情况仍需 canonical:
- 新站存在多个入口:比如
https://example.com/page和https://example.com/page/都能访问同一内容 - UTM 参数、A/B 测试 ID、分享追踪码等动态参数仍在使用,且无法在服务器层统一剥离
- CDN 缓存或代理层偶尔绕过 301 规则,导致旧 URL 被直接返回内容
注意:canonical 不能替代 301。没有 301 只靠 canonical,外部链接权重几乎不传递,Google 明确表示它只是“弱信号”,而 301 是“强指令”。
验证时重点看三件事:状态码、跳转链、canonical 值
上线后别只点开网页看是否跳转成功。真正要查的是:
- 用
curl -I https://old.com/old-path确认返回的是HTTP/2 301,不是200或302 - 检查有没有跳转链:比如
old → middle → new,多跳会损失权重,应尽量保持 1 跳直达 - 用浏览器开发者工具查看新页源码,确认
<link rel="canonical">的href是绝对 URL、协议一致、无拼写错误
最容易被忽略的一点:旧 URL 如果因 CDN 缓存或本地 hosts 修改仍可直连,它的 canonical 很可能没被更新——这时候搜索引擎看到的仍是“旧页自称旧页”,权重就卡住了。



















