搜索抓取

前端路由与 URL 发现:哈希地址与真实路径差在哪

单页应用里,哈希地址和历史模式在 URL 发现上的表现完全不同。本文从前端路由出发,说明井号地址为什么难以被当作独立页面、历史模式直连为什么会返回 404、源码里只有 onclick 的链接为什么跟不到,并给出一套从源码到服务器日志的自查顺序。

搜索抓取

前端路由与 URL 发现:哈希地址与真实路径差在哪

发现的前提是地址能被当作独立页面

URL 发现这件事,很多时候不是蜘蛛不愿意抓,而是它根本没把某个地址当成一个页面来看。前端路由常见的两种写法——哈希模式和历史模式——在这一点上差别很大,但不少站点把它们当成一回事,结果就是页面在站内点得到,却迟迟没有独立的抓取记录。

哈希地址长这样:example.com/#/list/2。浏览器发起请求时,井号之后的内容不会发送给服务器,服务器永远只看到 example.com/ 这一层。对蜘蛛来说,站内所有哈希路由都指向同一个资源,无法作为不同 URL 被分别发现。即便页面上有完整内容和可点链接,这些内容也很难进入独立的抓取与索引流程。

历史模式看起来正常:example.com/list/2。它确实是独立路径,但是否能被发现,取决于两件事:服务器能不能对该路径直接返回页面,以及源码里有没有可跟随的链接。

历史模式的三个常见坑

直连返回 404

单页应用通常把路由交给前端处理,服务器只配置了根目录。蜘蛛拿着 /list/2 这个地址去直连时,服务器找不到对应文件,返回 404。它不会因为你在站内点击能打开就认为这个地址有效,404 就是 404。要解决就得在服务器端配置回退,让前端路由路径统一返回入口页面,并给出 200 状态码。

源码里只有 onclick

很多列表是这样写的:一个 div 或 span,绑定点击事件后调用路由跳转。这种做法对人没问题,对蜘蛛就不行——HTML 源码里没有 href,解析阶段看不到这条边。除非它愿意执行 JavaScript 并等待渲染完成,否则这个入口等于不存在。把可点击元素换成真正的 a 标签,写上完整 href,是最省事的改法。

渲染依赖被挡住

就算蜘蛛愿意渲染,JS 文件、接口请求、样式字体这些资源如果被 robots.txt 拦了,或者在超时时间内没能返回,渲染出来的页面就是空的,链接自然也拿不到。检查一下 robots.txt 里有没有误挡静态资源目录,以及接口响应时间是否够稳定。

自查顺序:从源码到日志

  1. 用 curl 或查看网页源代码的方式取一次 HTML,搜索关键路径是否出现在 href 里。要看初始源码,渲染后的 DOM 不算数。
  2. 直接访问几个深层路径,确认状态码是 200,而不是 404 或被重定向到首页。落到首页同样会让蜘蛛认为该路径没有独立内容。
  3. 在服务器日志里筛出蜘蛛的访问记录,看它有没有真的请求过这些路径。请求过但状态异常,和压根没请求,是两类问题,处理方向完全不同。
  4. 把关键路径写进 Sitemap 作为补充入口,但不要把它当成万能兜底——Sitemap 只提供发现线索,能不能抓仍然取决于响应状态和页面内容。

更稳妥的结构选择

如果内容和流量依赖搜索,列表页、详情页这类核心页面尽量走服务端渲染或静态生成,让 HTML 直出时就有完整链接和内容。前端路由可以用在交互密集、对发现不敏感的部分,比如后台、设置页、弹窗流程。

另外,站内至少保留一条纯 HTML 的导航路径:底部导航、栏目列表、相关推荐,用 a 标签直接列出。这条路径不依赖脚本,哪怕前端渲染环节出问题,蜘蛛仍然有路可走。

判断标准很简单:把 JavaScript 关掉,页面上的链接还能不能点、能不能跳。不能的话,URL 发现这一环就要打个问号。