说到结构化数据,大多数人真正困惑的并非“要不要添加”,而是“添加后为何毫无效果”。JSON-LD 表面上看只是一段简单的脚本,但 Googlebot 对它有非常严格的要求——它不会执行任何 JavaScript,也不解析 DOM,只会死磕原始 HTML 中直接输出的纯脚本块。因此,这条规则必须牢记:JSON-LD 只能直接放在 或 中,绝对不能嵌套在 、、 这类标签里。不少人在 Search Console 中看到“未检测到结构化数据”,翻源码明明存在,一查才发现是被框架动态插入(如 Next.js 的 useEffect),或者 CMS 模板无意间将其塞进了 ——这些都属于无用功。

如果你的项目采用 SSR 或静态站点(Hugo、Jekyll 等),天然具备优势,直接写进模板即可。而 React/Vue 项目则必须确保脚本在服务端渲染阶段就输出,千万不要拖到客户端挂载。另外还有一条铁律:async、defer 或 type="module" 这类属性一律不能加,加了浏览器会直接跳过解析,等于白写。
JSON-LD 到底该放在 还是 ?
前文已经明确:两者都可以,但前提是直接输出且不被嵌套。常见的翻车原因是框架把脚本“藏”起来了。请记住:Googlebot 只扫描最外层的 块,只要嵌套在任何容器标签内,都会被判定为无效。
json_encode() 动态生成 JSON-LD 时容易踩的坑
很多后端开发者习惯用 PHP 或 Node.js 的 json_encode() 拼接结构化数据,虽然方便,但默认参数下的输出常常埋下隐患——HTML 实体未被处理、中文被转成 uXXXX、斜杠被转义,导致字段直接损坏。尤其是在 CMS 文章页、商品详情页这类场景中,字段从数据库取出直接使用,稍不注意就会引发非法格式。
- 务必带上
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES参数,防止中文和斜杠被转义。 - 所有字符串字段(如
headline、description等)在拼接前要经过htmlspecialchars($str, ENT_QUOTES, 'UTF-8')处理,既能防范 XSS,也能避免引号破坏 JSON 结构。 - 生成后应调用
json_last_error()检查是否成功,失败则记录日志,切勿静默忽略。 - 不要在循环中多次
json_encode()拼接多个对象——正确的做法是用数组先 push,最后一次性json_encode()整个数组。
Article 类型明明加了,为什么还是不显示富摘要?
许多人以为写了 "@type": "Article" 就能触发富摘要,但 Google 只认三要素齐全且格式严格匹配的组合,缺少任何一个字段或格式不匹配都会被静默忽略。而且这个类型仅适用于单篇正文页(如博客、新闻稿),在列表页或首页硬塞反而会降低可信度。
headline:必须是字符串,不能为空或纯空格。datePublished:必须采用 ISO 8601 格式,例如"2026-07-01T10:30:00+08:00";"2026-07-01"可以接受,但"2026/07/01"或中文日期会直接失效。author:必须写成对象形式,包含"@type"和"name",例如{"@type": "Person", "name": "张三"};只写字符串"author": "张三"不会生效。image字段的 URL 必须返回 200、可公开访问,且使用绝对路径(以https://开头)。
本地用 Rich Results Test 验证时报错,但源码看着没问题?
工具提示“无法解析”或字段缺失,通常不是逻辑问题,而是环境干扰或细节遗漏。性能影响几乎为零,但验证环节最容易踩坑。
- 浏览器插件(尤其是广告拦截、隐私保护类)可能过滤掉
,测试前务必禁用。 - 将 HTML 复制粘贴到工具时,确认包含完整的
块,且编辑器没有自动删除末尾逗号或换行。 - 相对路径(如
"image": "/img/logo.png")会被判为无效,必须转为绝对 URL。 @context必须严格写成"https://schema.org",写成http或拼写错误(如schem.org)都会导致失败。
实际部署时最容易被忽略的一点是:JSON-LD 不是“加了就行”,而是要“加对才有效”。哪怕一个字段类型错位、一个引号用了单引号、一个 URL 缺少协议头,Google 都不会报错,只会安静跳过——你必须依靠工具逐项核验,而不是凭肉眼扫一眼就上线。
