agentgrade

EnglishEspañol日本語中文
← 知识库

什么是 "JavaScript 渲染"?

一个页面是 JavaScript 渲染的,意味着服务器发送的 HTML 实质上是空的 — 实际内容(标题、正文、产品信息)只有在浏览器下载并运行了一个 JavaScript 包,把 React、Vue、Svelte 或 Angular 这样的框架挂载到一个空的根元素之后才会出现。

典型的 JS 渲染主页在网络上看起来是这样:

<body>
  <div id="root"></div>
  <script type="module" src="/assets/index-D9LVtTP6.js"></script>
</body>

可见的 <body> 内容是零字节。你在浏览器中看到的一切都是 JS 运行之后在客户端构造出来的。

为什么对智能体很重要

大多数 AI 爬虫不执行 JavaScript。当 ChatGPT、Claude、Perplexity、Gemini 的抓取或典型的智能体框架访问你的 URL 时,他们拿到的是原始 HTML — 而你的主页是空白的。你的产品描述、标题、链接和正文对他们来说都是不可见的。

这对检索和摘要是真正的伤害。当一个 LLM 在引用你的 URL 时被问到 "这家公司是做什么的?",它会产出糟糕的回答或产生幻觉,因为页面上没有任何东西可读。

不会 破坏什么

输出到 HTML 静态 <head> 中的标签不受客户端渲染的影响。即使是完全 JS 渲染的 SPA,只要构建工具正确填充了 head,这些检查仍然可以通过:

如果你的站点是 JS 渲染的,而且 这些检查也都失败了,那是独立的缺口 — 通过给构建的 HTML 模板加上正确的 <head> 标签来修复,不论是否修复渲染本身。

共同的根本原因: 静态托管的 SPA 包

JS 渲染的站点通常以静态包(一个 index.html 和一个 JS/CSS 文件夹)交付,部署到对任何 GET 请求都返回 index.html 的主机上: Vercel 静态、Netlify、Cloudflare Pages、GitHub Pages、S3 + CloudFront、Fastly Frontend、Firebase Hosting。

这种部署模式根本没有任何按请求的服务器端逻辑。产生 JS 渲染 body 的同一份配置, 会产生:

不触及部署模型而单独修复一个症状(例如内容协商)通常是不可能的 — 你需要服务器端逻辑,或者在静态包前面放一个边缘函数。

修复阶梯

挑选能解决你情况的最低成本选项。

1. 构建时预渲染

如果主页内容主要是静态的,在构建期间预渲染。浏览器仍然会用 React/Vue 等进行水合,但服务器发送的初始 HTML 已经包含渲染后的 DOM。爬虫看到真实内容。

对营销页面、博客和文档来说,这是最低成本的修复。

2. 完整的服务器端渲染(SSR)

如果主页需要动态数据(登录态、A/B 测试、新鲜内容),使用每次请求都渲染的框架:

SSR 需要一个运行时(Node、Bun、Deno 或边缘运行时),意味着离开纯静态托管。

3. 用于内容协商的边缘函数

如果迁移到 SSR 太破坏现状,在静态包前面放一个边缘函数,拦截请求并返回备用表示:

// Cloudflare Worker / Vercel Edge / Netlify Edge
export default async function (request) {
  const accept = request.headers.get('accept') || '';
  const ua = (request.headers.get('user-agent') || '').toLowerCase();
  const isAgent = /claudebot|gptbot|chatgpt-user|perplexitybot|google-extended/.test(ua);

  if (isAgent || accept.includes('text/markdown')) {
    return new Response(await fetchMarkdownSummary(), {
      headers: { 'Content-Type': 'text/markdown', 'Vary': 'Accept, User-Agent' },
    });
  }

  return fetch(request); // 透传到静态包
}

当底层应用必须保持客户端渲染(例如重交互应用)时,这是合适的修复 — 但你仍然希望智能体读到有意义的内容。

4. <noscript> 兜底(最小可行)

至少在静态 HTML 的 <noscript> 块里放上你的关键内容:

<noscript>
  <h1>你的公司</h1>
  <p>你做什么,两句话说清。链到文档、价格、API。</p>
  <a href="/about">关于</a> · <a href="/docs">文档</a> · <a href="/pricing">价格</a>
</noscript>

这不能代替预渲染,但能避免爬虫看到完全空白的页面。大多数 JS 渲染的站点并没有这一项。

如何验证

不执行 JavaScript 地抓取你的站点,看看 body 里是否有真实内容:

curl -s -A "ClaudeBot/1.0" https://yourdomain.com/ | \
  python3 -c "import sys, re; t = sys.stdin.read(); body = re.search(r'<body[^>]*>(.*?)</body>', t, re.S); print(len(re.sub(r'<[^>]+>', '', body.group(1) if body else '').strip()))"

如果打印出来的数字小于几百个字符,智能体看不到你的内容。

了解更多

相关