事情本身不复杂,线索都在日志里。上线了一个 HTML 压缩插件之后,结构化数据在源码里变成了 "@type": "Article" 这种形态。浏览器渲染看不出区别,富媒体测试工具直接提示无法提取,站内所有文章的富媒体在同一天全部消失。
第一反应是「CDN 的 HTML 改写功能对 application/ld+json 也做了处理」,验证下来不成立。
真正麻烦的地方在于,几个原因的现象几乎一样。压缩插件把 script 标签内的内容也做了实体转义。另一种情况是模板用了 esc_html 而不是 esc_attr 输出 JSON 字符串。
少数情况下是多个压缩插件叠加 第二次处理把已转义的实体又转了一遍。
动手时先看源码里 JSON-LD 的实际形态
curl -s https://www.example.com/post/123 | grep -A2 'application/ld+json' | head -5
随后确认输出时没有做 HTML 实体转义
echo '<script type="application/ld+json">' . wp_json_encode($data) . '</script>';
然后在压缩插件里排除该 script 类型
add_filter('autoptimize_filter_html_noptimize', fn($s) => $s . ',application/ld+json');
末了清缓存后复验转义字符数量
curl -s https://www.example.com/post/123 | grep -c '"'
怎么算真的好了,看的是同一批现象。关掉对 JSON-LD 的压缩处理后,源码里的引号恢复原样,测试工具能正常提取,富媒体在重新抓取后陆续回来。
这里还有个坑。任何对 script 内容做处理的优化手段都要先确认它不动结构化数据,这类问题排查时最容易被忽略。这类问题最好一次改到位,反复小改反而容易把原因搅混。
