技术知识文章集合TECHNICAL ARCHIVE · 457 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTVUE

SPA单页面应用、前后端分离项目SEO优化的方法

所属馆藏
Vue
文件格式
Markdown
原始路径
Vue/04-SPA单页面应用、前后端分离项目SEO优化的方法
本文目录9 个章节
  1. 前言
  2. 一、2026 年首选:SSR、SSG 与混合渲染
  3. 二、页面级 SEO 基线
  4. 三、URL:path 与 query 都可以规范使用
  5. 四、原 Prerender + Nginx 方案
  6. 五、动态渲染的现代风险与过渡边界
  7. 六、部署检查清单
  8. 总结
  9. 官方参考

SPA单页面应用、前后端分离项目SEO优化的方法

Category(分类): Vue Status: 已校订(历史方案 + 2026 现代 SEO)

前言

原作者的博客采用前后端分离:前端通过 Ajax 获取接口数据,再在浏览器中渲染。早期搜索引擎对 JavaScript 的渲染能力有限,因此原作者观察到收录页面只包含 HTML 中写死的文字。

原文配图 04-01

原文配图 04-02

这段经历有历史价值,但到 2026 年需要修正两点:

  1. Google 可以渲染 JavaScript。 Googlebot 使用 evergreen Chromium,处理大致经历 crawling → rendering → indexing;但渲染可能排队,且会受到资源阻断、接口失败、超时、兼容性和性能影响。并非所有爬虫都可靠执行 JavaScript。
  2. SPA 不是天然无法 SEO。 可抓取的真实链接、稳定 URL、可访问资源、正确状态码和渲染结果都很重要。不过对于文章、营销页等公开内容,让关键正文直接出现在首个 SSR/SSG HTML 中通常更稳妥,也有利于真实用户首屏体验。

百度曾公布带渲染能力的 Baiduspider-render/2.0,因此不能再断言“百度蜘蛛执行不了 JS”;面向百度仍应以当前站长平台的抓取诊断、服务器日志和真实页面验证为准。

一、2026 年首选:SSR、SSG 与混合渲染

对公开文章站,优先级通常是:

  • SSG / 构建时预渲染:内容发布时生成每个 URL 的完整 HTML,适合更新频率可控的文章;
  • SSR:请求时由服务端返回页面 HTML,适合实时或个性化程度较低的公开数据;
  • 混合渲染:按路由选择预渲染、SSR、缓存或 CSR;
  • 纯 CSR:更适合登录后后台、强交互且不需要收录的页面。

SSR/SSG 并非没有成本:SSR 需要服务端资源和缓存策略,hydration 需要客户端 JavaScript;SSG 则要处理构建时长与内容更新。但它们避免让重要正文依赖搜索引擎第二阶段渲染,通常是内容站的现代首选。

Nuxt / Nitro 示例

Nuxt 4 默认支持 universal rendering,也可为特定路由设置预渲染规则:

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/articles/**': { prerender: true },
    '/admin/**': { ssr: false },
  },
})

页面元信息可使用 useSeoMetauseHead

<script setup lang="ts">
const route = useRoute()
const article = await useFetch(
  () => `/api/articles/${route.params.id}`,
)

useSeoMeta({
  title: () => article.data.value?.title ?? '文章',
  description: () => article.data.value?.summary ?? '',
  ogTitle: () => article.data.value?.title ?? '文章',
})

useHead(() => ({
  link: [
    {
      rel: 'canonical',
      href: `https://example.com/articles/${route.params.id}`,
    },
  ],
}))
</script>

实际项目还要处理不存在文章的 404、数据获取失败和 HTML 转义,不能让所有未知 ID 都返回同一份 200 页面。

二、页面级 SEO 基线

渲染方式只是起点,每个可索引页面还应做到:

  1. 规范 URL:为每份内容选定唯一、稳定的 canonical URL;旧地址用 301 合并。
  2. 元信息:独立、描述性的 <title> 与 description;社交分享可补 Open Graph。
  3. 结构化数据:按内容使用符合 Google 规范的 JSON-LD(如 Article),字段必须与页面可见内容一致。
  4. 可抓取链接:站内导航输出真实 <a href="/articles/...">,不要只靠 click handler 或 #/...
  5. Sitemap 与 robots:sitemap 只列规范、可索引 URL;robots.txt 不要误挡渲染所需的 JS、CSS、图片和 API。
  6. 正确状态码:不存在页面返回 404,永久迁移返回 301;不要把错误页统一返回 200 index.html,否则可能形成 soft 404。
  7. 可访问正文:标题、正文、关键链接最好在首个 SSR/SSG HTML 中;延迟加载不能依赖点击或滚动才让爬虫看到主要内容。
  8. 性能与稳定性:控制 JavaScript 体积,确保服务端和 API 可靠,避免渲染阶段出现控制台或网络错误。

部署后应使用 Google Search Console URL Inspection、Rich Results Test、抓取日志和实际 HTML 检查,而不是仅凭搜索截图判断。

三、URL:path 与 query 都可以规范使用

原文认为 /articles/?id=xxx 天生不友好、爬虫只喜欢 /articles/xxx,这个结论过于绝对。Google 可以抓取规范的 query URL。可读 path 往往更利于用户理解和分享,但决定因素是 URL 稳定、可发现、无重复和有统一 canonical。

如果两个地址都能访问同一篇文章:

/articles/123
/articles/?id=123

应选一个作为公开 canonical,并用 301 或 rel="canonical" 合并信号。Nginx 内部 rewrite 可以兼容旧后端,但 rewrite 本身不等于 SEO 优化:

# 历史兼容示意:公开 URL 仍是 /articles/123
rewrite ^/articles/(\d+)$ /articles/?id=$1 break;

还必须保证不存在的 ID 返回 404,并避免两个入口长期产生重复内容。

四、原 Prerender + Nginx 方案

历史方案,请勿直接照抄。 以下按原作者当年的实践恢复安装、守护、分流、测试和 rewrite 上下文,仅用于理解遗留 dynamic rendering。相关仓库、依赖、无头浏览器与 Nginx 安全边界都可能已变化;新项目优先采用前文 SSR/SSG。

原方案启动一个 Prerender 服务,用无头浏览器执行页面 JavaScript并返回 HTML;Nginx 按 User-Agent 判断爬虫,把爬虫请求转给 Prerender,普通用户仍访问 CSR 页面。这属于 dynamic rendering(动态渲染),不要与“构建时为所有用户生成同一份静态 HTML”的 SSG 混淆。

4.1 安装、启动与 curl 验证(历史命令)

原文要求先有 Node.js 和 Git 环境,然后执行:

# 历史记录,请勿直接作为现行安装步骤
# 该仓库路径/启动方式在当前版本可能已失效

git clone https://github.com/prerender/prerender.git
cd prerender
npm install
node server.js  # 原文默认监听 3000 端口

启动后,原作者用完整站点 URL 请求本地渲染服务;若返回执行 JavaScript 后的正文,就认为服务已启动:

# 将“你的网站全路径”替换为带协议的实际 URL
curl http://localhost:3000/你的网站全路径

原作者用 curl 验证 Prerender 启动结果(04-03)

这只能验证当时本机服务的一次输出,不代表状态码、缓存、资源加载和搜索引擎收录均正确。

4.2 forever 进程守护(历史命令)

原作者指出,终端关闭后直接运行的 Node.js 进程会退出,于是使用当年的 CLI 工具 forever 保持 server.js 运行:

# 历史方案,请勿直接照抄
npm install forever -g
forever start server.js
forever list
forever stop server.js
forever restartall

实际操作是在 prerender 根目录运行 forever start server.js

原作者在进程守护说明后的过渡表情图(04-04)

forever 不解决服务健康检查、日志轮转、安全更新、缓存、状态码或自动回滚;现代部署应按运行环境使用受维护的进程/容器编排能力。

4.3 完整 Nginx bot 分流(历史配置)

原作者让普通用户访问原 CSR 地址,让列出的爬虫 User-Agent 代理到 Prerender:

# 历史方案,请勿直接照抄
location / {
  # 表示是否需要代理
  set $prerender 0;
  set $prerender_url "http://127.0.0.1:3000";

  if ($http_user_agent ~* "baiduspider|Googlebot|360Spider|Bingbot|Sogou Spider|Yahoo! Slurp China|Yahoo! Slurp|twitterbot|facebookexternalhit|rogerbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
    set $prerender 1;
  }

  if ($prerender = 1) {
    proxy_pass $prerender_url;
    rewrite ^(.*)$ /https://$host$1 break;
  }
}

配置后,原文使用 nginx -s reload 重载。这里恢复的是历史原貌,不表示这种 if、变量 proxy_pass、协议写死和 UA 清单适合当前生产环境。

4.4 两组 curl 测试(原作者当时的比较)

普通用户请求:

curl https://你的网站全路径

原作者当时观察到返回的是未执行页面脚本的壳内容:

原作者普通用户 curl 结果(04-05)

模拟 Googlebot 请求:

curl -H 'User-agent:Googlebot' https://你的网站全路径

原作者当时观察到请求命中 Prerender,返回了解析后的正文:

原作者模拟 Googlebot curl 结果(04-06)

这两组命令只能证明配置对给定 UA 的分流结果,不能证明请求者是真实 Googlebot,也不能证明页面最终会抓取、渲染、索引或获得排名。

4.5 文章 URL rewrite(历史配置)

原作者希望把公开地址从 /articles/?id=xxx 表现为 /articles/xxx,先给普通访问增加内部 rewrite:

rewrite ^(.*)/articles/(\d+)$ /articles/?id=$2 break;

然后分别处理爬虫的快照 URL 和普通用户的 REST 风格地址:

# 历史方案,请勿直接照抄
if ($prerender = 1) {
  proxy_pass $prerender_url;
  rewrite ^(.*)/articles/(\d+)$ /https://$host/articles/?id=$2 break;
  rewrite ^(.*)$ /https://$host$1 break;
}

rewrite ^(.*)/articles/(\d+)$ /articles/?id=$2 break;

浏览器地址栏保留 /articles/xxx,服务器内部访问旧 query 入口。原作者随后测试了该 rewrite:

原作者文章 URL rewrite 测试(04-07)

但 query URL 并非天然不友好,rewrite 本身也不等于 SEO 优化;仍要处理 canonical、重复入口、重定向策略和不存在 ID 的 404。

4.6 原作者当时的最终效果

原作者根据搜索结果截图认为 Google 收录效果明显改善,并把它作为个人实践结论:

原作者当时观察到的最终 SEO 效果(04-08)

这是历史个案,不能由一张搜索截图推导出通用因果关系,排名也会受内容、链接、抓取、性能等多种因素影响。

五、动态渲染的现代风险与过渡边界

Google 现在明确把 dynamic rendering 定义为 workaround,而不是推荐的长期方案。旧文中的仓库启动路径在资料核查时已不可直接验证,forever 也只是旧式 Node 进程守护工具。

按 User-Agent 分流还存在以下风险:

  • User-Agent 可伪造,bot 列表会过时;真实 Googlebot 应通过反向 DNS 或官方 IP ranges 验证;
  • 为 bot 和用户维护两套渲染路径,会增加缓存不一致和故障面;
  • 内容实质不同可能构成 cloaking;
  • 快照可能缓存 API 错误、“加载中”或过期内容。

若遗留站确实暂时无法迁移 SSR/SSG,并且目标爬虫不能执行 JavaScript,可按当前供应商文档把动态渲染作为过渡层,但必须审计和锁定依赖,配置鉴权、缓存与失效,处理超时、监控、回滚和一致状态码,并保证用户与爬虫看到的主要内容实质相似,最终迁移到 SSR/SSG。

六、部署检查清单

无论采用 Nuxt SSR、SSG 还是遗留 dynamic rendering,都应检查:

  • 根地址与文章深层 URL 首次直达;
  • 站内导航和深层 URL 刷新;
  • 未知页面是否返回真实 404,而不是 200 shell;
  • API、JS、CSS、图片、robots.txtsitemap.xml 是否可访问;
  • canonical、title、description 与结构化数据是否逐页正确;
  • query/path 双入口和旧 URL 是否 301/规范化;
  • SSR/快照是否包含实际正文,而不是 loading;
  • 移动端、Search Console 渲染 HTML、网络资源和 JavaScript 错误;
  • 缓存发布后是否会让 HTML 引用已删除的哈希资源。

总结

  • Google 能渲染 JavaScript,但存在渲染队列、资源和失败风险;其他爬虫能力不一。
  • 公开内容的现代首选是 SSR、SSG 或混合渲染;Nuxt/Nitro 已提供直接路径。
  • Dynamic rendering / Prerender + bot 分流只适合遗留系统的过渡兼容,不再是 Google 推荐方案。
  • Query 参数不是天然不友好;应解决的是规范 URL、重复内容和状态码。
  • SEO 还需要元信息、结构化数据、真实链接、sitemap、robots、性能和可验证的抓取结果共同配合。

官方参考

作者:AnLingYi 原文链接:https://juejin.cn/post/6844903789661519886 来源:稀土掘金。著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

457 DOCUMENTS · 10 COLLECTIONS
ARCHIVE SEARCH457 篇文章

SEARCH GUIDE

输入关键词开始搜索

支持搜索文章标题、所属分类和原始文档路径。

按分类浏览

10 COLLECTIONS