
症状
两个看起来毫不相干的问题,其实是同一类:
- 后台把首页标题改了,刷新前台还是旧的;用无痕窗口、换个浏览器还是一样。
- 页面源码里出现了两份
<link rel="canonical">、两份og:标签,甚至一份是英文一份是中文。
它们共同的根因是:你改了"数据层",但"输出层"用的还是早就算好的旧结果。
一、先记住排查顺序:三层缓存,从外到内
| 层 | 谁在缓存 | 怎么清 |
|---|---|---|
| 页面缓存 | WP Super Cache 等插件生成的整页 HTML | 后台插件页「删除缓存」,或调插件的清缓存函数 |
| 对象缓存 | Redis / Memcached 缓存的数据库查询结果与选项 | 后台 Redis 插件「清空对象缓存」 |
| CDN / 浏览器 | 边缘节点、浏览器本地缓存 | 刷新 CDN 缓存;浏览器用无痕或强制刷新 |
排错时按这个顺序,一层层排除,不要一上来就怀疑代码。
一个诊断技巧:分清是"缓存"还是"代码"
# 加一个随机参数就是"绕过页面缓存"的信号(WP Super Cache 的规则里带 query 不缓存)
curl -s 'https://www.mokiii.com/?nocache=1' | grep -o '<title>[^<]*</title>'
curl -s 'https://www.mokiii.com/' | grep -o '<title>[^<]*</title>'
- 两条不一样 → 是页面缓存问题(带参数的走了 PHP,不带参数的吃了缓存文件);
- 两条一样 → 缓存不是元凶,去看对象缓存或代码。
二、案例一:改了主题设置,前台纹丝不动
现象:在后台改了首页 SEO 标题,前台首页、无痕窗口、手机看全是旧的。
排查:按上面的技巧一测,带参数的输出是新的,不带参数的是旧的 → 确认是页面缓存。
根因:站点用的是 WP Super Cache 的 mod_rewrite 静态直出——nginx 直接返回缓存文件,请求根本不进 PHP,所以"清缓存"这件事必须显式做。而 WPSC 只在编辑/发布文章时自动清缓存($wp_cache_clear_on_post_edit = 1),保存主题设置、改小工具、改分类设置都不会清。
修复:清一次页面缓存即可。用插件自带的函数(等价后台「删除缓存」按钮):
// 放在一段一次性脚本里执行
if ( function_exists( 'wp_cache_clear_cache' ) ) {
wp_cache_clear_cache( 0 );
}
更好的做法:让它在保存设置时自动执行。
add_action( 'updated_option', function ( $option ) {
// 主题选项、ACF 选项页、小工具变更后清一次页面缓存
if ( 'theme_options' === $option || 0 === strpos( $option, 'options_' ) || 0 === strpos( $option, 'widget_' ) ) {
if ( function_exists( 'wp_cache_clear_cache' ) ) {
wp_cache_clear_cache( 0 );
}
}
}, 20 );
核心认知:静态直出的站点,"写入数据"和"重新生成页面"是两件事。 任何绕过后台表单的修改(直接写数据库、跑脚本、改配置文件)都不会自动触发页面重新生成。
三、案例二:源码里有「双份」SEO 标签
现象:页面里同时有两套标签——两行 canonical(一行带尾斜杠一行不带)、两套 og:(一套 zh_CN 一套 zh_Hans)、描述还是旧的。
根因:两套 SEO 在同时输出。常见组合是「主题自带的 SEO」加上「装了 SEO 插件(比如 Rank Math)」,两边都在 wp_head 里打标签。
怎么确认:
# 各标签出现次数,大于 1 就是重复
curl -s https://www.mokiii.com/ | grep -oE '<title>|rel="canonical"|property="og:title"|name="description"' | sort | uniq -c
怎么修:只留一套,关掉另一套。不要试图用 CSS 或 JS 去藏——搜索引擎读的是源码。
以「主题自带 SEO + Rank Math」为例,正确做法是保留 Rank Math,关掉主题那一侧:
- 先在主题/框架的设置面板里找 SEO 开关关掉;
- 关掉后必须再检查一遍源码(见下面的验收标准);
- 如果面板里关了但前台还有,说明那个开关实际控制的不是输出——得找出真正控制输出的那个开关再改。
验收标准(每一项都应为 1):
curl -s https://www.mokiii.com/ -o /tmp/h.html
for t in '<title' 'rel="canonical"' 'property="og:title"' 'property="og:description"' 'name="twitter:title"' 'name="description"'; do
printf '%-30s %s\n' "$t" "$(grep -oF "$t" /tmp/h.html | wc -l)"
done
顺带说清:哪些"看起来重复"其实正常
修完之后你会看到标题和描述各出现了 3 次,这是设计如此、不是重复:
| 标签 | 给谁看 |
|---|---|
<title> / <meta name="description"> | 搜索引擎结果页 |
og:title / og:description | 微信、QQ、微博、Facebook 等分享卡片 |
twitter:title / twitter:description | X(Twitter)卡片 |
canonical / og:url | 同一地址的两种用途:规范地址、分享链接 |
判断标准很简单:同一个用途出现两次才是 bug(比如两行 canonical),不同用途各一份是正常的。
四、把顺序固化成清单
下次遇到"改了没生效",照这个走:
- 用
?nocache=1判断是否为页面缓存; - 是 → 清页面缓存(并检查是否静态直出、是否需要在设置变更时挂钩子);
- 否 → 清对象缓存,再看是否代码层问题;
- 都排除了 → 检查是否两套东西在输出同一内容(SEO 标签、CDN 注入、主题与插件重复渲染);
- 修完必须用源码计数验收,不要只看浏览器里"好像变了"。
一句话总结:改了没生效,先分清是"数据没写进去"还是"输出层没重算"。静态直出的站点尤其要记住:写数据和重新生成页面是两件事;而源码里出现两份同用途标签,几乎一定是两套 SEO 同时开着。

评论 (0)