前段时间把程序员网址导航网站 w3to.dev 从 WordPress + WebStack-Pro 主题迁到了 Astro 7 静态站,部署在 Cloudflare Pages。
![]()
架构是清爽了,但 Google Search Console 的网页编制索引显示 90 多万条未找到页面(404)。
这篇文章就记录一下我用 301、404、410 三个状态码处理 Google 收录的链接失效后的补救的过程。
三个状态码的对于 SEO 含义以及对搜索引擎的影响
301:永久重定向。告诉搜索引擎"这个 URL 永久搬新家了",权重传递到新地址。迁移场景里,有对应新页面的旧 URL 用它。
404:未找到。页面没了,但搜索引擎不知道是临时还是永久,会保留一段时间继续爬,慢慢清除。
410:永久消失。RFC 9110 定义是"资源被故意删除,永久不会再有"。语义比 404 更明确。
有个流传很广的说法,"410 比 404 处理快,删页面该用 410"。
Google 官方状态码文档把 404 和 410 归在同一条目,原话是"All 4xx errors, except 429, are treated the same",等同处理。
这次用 410 不是为了快,而是语义明确:这些 URL 是新版本没有的,也不会再有。
URL 映射策略:精确 301 + 模式 410 兜底
90 多万条 404 不能无脑全 301 到首页,要先分析数据:
从 GSC 截图样本看,404 的 URL 模式主要两类:
1. 旧 WebStack-Pro 条目页:/products/{14-15位数字}、/dp/{12-15位数字},占前 10 条里的 7 条。旧 WP 导航站的商品条目页,新站没对应内容。
2. WP 标准归档:/tag/、/author/、/en/favorites/term-6 等,WordPress 自动生成的归档页,新站根本没这套结构。
映射策略分三档:
高价值 URL → 精确 301 重定向跳转。 有对应新页面的,一条条映射。现有 public/_redirects 446 行,其中 362 条 /sites/{id}.html → /sites/{slug} 精确 301、32 条 /favorites/{slug} 分类 301、22 条 /favorites/term-{id} 301。迁移前后能对上的,必须精确跳转保权重。
废弃归档 URL → 模式 410。 /tag/、/author/ 这些 WP 标准归档,新站彻底不做,用 410 明确告诉搜索因为页面没了。
最忌讳的:批量 301 到首页。 很多人图省事把所有 404 都 301 到首页,这是软 404。Google 迁移指南原话:"Don't redirect many old URLs to one irrelevant single URL destination, such as the home page of the new site. This can confuse users and might be treated as a soft 404 error."
软 404 比真 404 还糟:Google 判定你在糊弄,把重定向当 404 处理,还可能连累首页信号。90多万条全 301 到首页,等于告诉搜索引擎"网站首页是垃圾回收站"。
Cloudflare Pages 的重定向能力边界
策略定了,落地卡在 Cloudflare Pages 的能力上。
_redirects 不支持 410,这文件只认 301/302/303/307/308,写 410 直接被拒。我试过 /blog/* /blog/404.html 410,构建报错。
410 得用 Pages Functions 实现。写一个 functions/[[path]].js,匹配废弃归档 URL 模式,直接返回 410。
但有个坑。Cloudflare 官方文档有个 Caution 框,原话:"Redirects defined in the _redirects file are not applied to requests served by Pages Functions, even if the Function route matches the URL pattern."
一旦请求被 Functions 接管,_redirects 规则就不生效。如果 Functions 路由覆盖全站,我那 400 多条现有 301 全得废。
解决方案是 _routes.json。它控制 Functions 生效范围,exclude 优先于 include,最多 100 条规则、每条 100 字符。我用 include 把 Functions 圈死在旧 WP 归档前缀,其余路径继续走 _redirects,两套机制互不干扰:
// functions/[[path]].js
export async function onRequest(context) {
// 匹配废弃归档模式,返回 410
return new Response('Gone', { status: 410 });
}
// _routes.json —— 圈定 Functions 生效范围
{
"version": 1,
"include": ["/tag/*", "/author/*", "/en/favorites/*"],
"exclude": []
}GSC 操作的两个易错点
前缀移除没有 1000 条限制。 网上传"GSC 一次最多移除 1000 条 URL",那个 1000 是 Sitemaps 报告的显示上限,不是移除工具的限制。前缀移除是一条请求覆盖该前缀下所有 URL。旧路径前缀下全是废弃页面,直接提交前缀移除,不用一条条删。
URL 检查工具不跟随重定向。 Google 的 URL Inspection Tools 不会跟随重定向链。用它验证"301 是否生效",看到的只是旧 URL 状态,不会跳到新地址。验证重定向效果用浏览器或 curl,别被 GSC 检查结果误导。
404 清理总结:301 / 410 怎么配
90 多万条 404 不是一天能清完的,但方向对了就不会错。简单记一下:
有对应新页面的,精确 301,保权重
彻底废弃的,用 410 图语义明确(别信"410 更快",Google 官方等同处理)
千万别批量 301 到首页,软 404 比真 404 还伤
另外别忘了重新提交 sitemap——迁移后新站的 sitemap-index.xml 要在 GSC 里重新提交一次,Google 才会优先爬新结构,索引恢复才能跑起来。
静态站部署在 Cloudflare Pages 的,记住 _redirects 管不了 410,得用 Functions + _routes.json 配合,一不留神 301 全废。
未经允许不得转载:w3h5前端开发资源网 » 网站迁移后收录的90多万条页面404补救:301/404/410实战清理
w3h5前端开发资源网