站点运营

站点运营:搜尋蜘蛛的URL發現,從單頁應用的前端路由说起

單頁應用的頁面切換靠前端路由完成,用戶觉得顺滑,但蜘蛛看到的可能只有一張 HTML。本文讨论 hash 與 history 模式的区別、首屏源碼里该如何保留真實連結,以及服務端渲染、预渲染和站点地图兜底的取舍。

站点运营

站点运营:搜尋蜘蛛的URL發現,從單頁應用的前端路由说起

用 Vue、React 或類似框架搭建的站点,頁面切換靠前端路由完成,用戶点起来很顺,但換到蜘蛛的视角,可能整站只看到一張 HTML。URL 發現的前提是頁面上存在能被点開、能被解析的連結,單頁應用恰好最容易在這個环节掉鏈子。

先分清 hash 模式和 history 模式

前端路由常见的两種寫法,對 URL 發現的影响完全不同。

  • hash 模式:地址形如 example.com/#/news/123。井号後面的部分不會作為獨立 URL 向服務器發起請求,蜘蛛即使拿到這個地址,抓到的也只是首頁那份 HTML,後面那段路由信息基本等于没有。
  • history 模式:地址形如 example.com/news/123,是真實、可請求的 URL。只要服務器做了回退配置,让未匹配的路径返回應用入口,蜘蛛就能直接拿到頁面。

所以如果内容頁還在用 hash 路由,優先把它改成 history 模式,這是最基础的一步。

首屏 HTML 里有没有連結

換成 history 模式只是让 URL 變真,接下来還要回答一個問题:服務器返回的這份 HTML 里,有没有下一层内容的入口?

不少單頁應用的入口 HTML 只有一個空容器,導航和列表全部由 JS 挂载。蜘蛛虽然越来越能执行 JS,但执行有预算、有超时,指望它把整站渲染一遍並不划算。更稳的做法是让入口 HTML 本身就带連結。

可以這样自查

  1. 用命令行請求一個栏目頁,看看返回的源碼里有没有指向内容頁的 href。
  2. 在浏览器里關掉 JavaScript,看看還能不能点到下一层。
  3. 對照服務端日誌,確認内容頁的 URL 是否被單獨請求過。
判断标准很简單:把 JS 關掉,如果頁面上還能顺着点下去,URL 發現基本就没有大問题。

几種務實的處理方式

服務端渲染或预渲染

對導航、栏目列表這類關键路径做服務端渲染或预渲染,輸出的 HTML 里直接带 a 标簽。改造范围不用铺满全站,先把主干走通即可。

首屏先輸出一批真實連結

列表頁不必等接口返回全部資料再渲染。首屏可以先輸出十几條真實連結,剩下的再用前端路由挂载。

路由懒加载別影响連結本身

按需加载组件没問题,但連結的 href 應该在 HTML 阶段就寫好,而不是点击时才用脚本跳轉。用 click 事件代替 a 标簽,蜘蛛拿不到入口。

用站点地图兜底

服務端渲染成本較高时,至少让 XML 站点地图覆盖全部内容 URL,作為一條獨立的發現通道。它不能替代内鏈,但能保證内容頁不至于完全没人带路。

几個常见坑

  • 所有路由都返回 200。不存在的詳情頁也返回應用外壳,等于给蜘蛛递了一堆内容相同的頁面。
  • 路由參數被無限拼接。篩選、排序、分頁參數组合出来的 URL 數量可能遠超真實内容。
  • 把導航寫死在 JS 數组里。連結存在,但不出現在 HTML 中。
  • 只在頁面底部放一個“加载更多”按钮,却不给對應的分頁 URL。

單頁應用不是不能被發現,而是要把“依赖 JS 才存在”的連結,變回“HTML 里就存在”的連結。這一层理顺了,抓取和收錄才有繼續讨论的余地。