WordPress特色图片失灵?控制台报错 _.contains is not a function —— 记一次由浏览器扩展冲突引发的诡异Bug排查实录
问题现象
某天,像往常一样在WordPress后台编辑文章,准备为文章设置一张特色图片。点击 “设置特色图片” 按钮,毫无反应。媒体库弹窗没有出现,页面就像被冻住了一样。
打开浏览器开发者工具(F12),控制台赫然出现一条红色报错(如图1):

Uncaught TypeError: _.contains is not a function
at r.1288.r.extend.get (media-models.min.js?ver=7.0:2:10536)
at Object._requery (media-models.min.js?ver=7.0:2:5065)
at Object._changeQuery (media-models.min.js?ver=7.0:2:2280)
at p (backbone.min.js?ver=1.6.1:2:3818)
...
每点击一次“设置特色图片”,报错就增加一条。这意味着WordPress后台的媒体库核心脚本(media-models.min.js)在执行时,找不到一个名为 _.contains 的JavaScript函数。
初步猜测:浏览器缓存?
按F5刷新,问题依旧。用Ctrl+F5强制刷新(绕过缓存),竟然好了!特色图片可以正常打开了(如图2)。然而,下一次新建文章时,问题又回来了,又得再次强制刷新。

这很奇怪:强制刷新已经重新下载了正确的脚本,为什么浏览器“记不住”?
我尝试了 Chrome无痕模式,结果第一次点击就完全正常,而且控制台没有任何报错(如图3)。这说明问题肯定与正常模式下的某些持久化数据或扩展有关。

排除Service Worker
我知道现代浏览器有Service Worker(一种独立缓存机制),很多PWA网站会用它拦截网络请求。难道是我的WordPress站点注册了Service Worker,缓存了旧的JS文件?
打开 chrome://serviceworker-internals/,仔细查看所有注册的Service Worker。列表里有一堆,但全都是浏览器扩展(chrome-extension://)或第三方网站(Google、Bing、Notion等),并没有我的WordPress域名(如图4)。排除了Service Worker的可能性。

转向浏览器扩展(插件)
无痕模式默认禁用所有扩展,而正常模式会加载所有扩展。两者唯一的区别就是扩展。因此,问题几乎肯定出在某一个或多个浏览器扩展上。
我安装了很多扩展:6个加密钱包(MetaMask, Phantom, Tonkeeper, Alby, OneKey, UniSat Wallet),还有Stylus、WPS浏览器助手、React开发者工具等。现在开始逐一排查。
第一次批量测试
我先禁用所有扩展,然后回到WordPress后台,点击“设置特色图片”——正常了!确认就是扩展冲突。
钱包扩展单独测试
接下来,我尝试只启用所有6个加密钱包扩展,禁用其他所有扩展。结果:问题复现(点击无反应,报错)。
那会不会是钱包扩展的锅?我尝试只启用MetaMask,其他全关。测试:正常。
只启用Phantom:正常。
只启用Tonkeeper:正常。
……每一个单独启用都没问题。
问题似乎只出现在多个钱包同时启用时。
二分法定位具体组合
我有6个钱包,全部启用时出错。我试着禁用其中一个,保留其他5个。
- 禁用UniSat Wallet → 其他5个启用 → 正常!
- 禁用MetaMask → 其他5个启用 → 仍然报错?等一下,不对,让我重新严谨测试。
经过反复交叉验证,最终得到确定结论:
当 UniSat Wallet 与 MetaMask 同时启用时,必定触发错误。
当 UniSat Wallet 与 Phantom 同时启用时,同样触发错误。
而 UniSat 单独启用,或者与其他钱包(如Tonkeeper、Alby、OneKey)同时启用,都没有问题。
这很有意思:问题不是单一扩展导致的,而是 UniSat Wallet 与 MetaMask 或 Phantom 之间的交互冲突。
单一扩展验证
为了确认,我做了最后一个测试:只启用 UniSat Wallet,禁用其他所有扩展(包括MetaMask、Phantom等)。结果:功能正常。说明UniSat本身并没有破坏WordPress后台,只是当它与其他某些钱包同时存在时,才会产生冲突。
冲突的根本原因
这些加密钱包扩展都会向页面注入JavaScript全局对象(如 window.ethereum),并且它们各自可能加载了自己版本的 lodash 或 underscore 库,并覆盖了全局的 _ 变量。
WordPress的 media-models.min.js 依赖于旧版Underscore.js提供的 _.contains 方法。一旦 _ 被某个扩展(或其依赖的库)替换为一个没有 contains 方法的对象(例如新版Lodash中该方法已更名为 _.includes),就会抛出 _.contains is not a function 错误。
当UniSat与MetaMask(或Phantom)同时运行时,它们对 _ 的争夺导致了版本不兼容,最终暴露了WordPress代码的脆弱依赖。
解决方案
找到了根源,解决办法就清晰了:
临时方案(推荐)
在使用WordPress后台写文章时,暂时禁用UniSat Wallet(如图5)(或者禁用MetaMask/Phantom,根据个人需求选择)。可以通过Chrome的扩展管理面板快速开关,或者安装一个扩展管理器(如SimpleExtManager)一键切换分组。
直接原因已经找到,应该是与我前段时间安装钱包扩展 Phantom 有关系了。正是因为 UniSat Wallet + Phantom 导致的问题。参考:V2EX 注册全攻略:从购买 V2EX 代币到解决 Phantom 插件卡死上岸

长期方案
- 向扩展开发者反馈:在GitHub或官方支持渠道提交issue,描述WordPress后台冲突现象,附上报错堆栈和复现步骤。希望他们在新版中修复对全局
_的污染。 - 使用Chrome多用户:创建一个专门用于网站管理的新Chrome用户(Profile),该用户不安装任何加密钱包扩展。写文章时切换到这个用户,完全隔离。
- 修改WordPress代码(不推荐):可以在主题
functions.php中强制重新加载Underscore.js,但这只是治标不治本,且可能影响性能。
总结与反思
这次排查经历让我深刻体会到:
- 浏览器扩展是网站后台故障的隐形元凶。当遇到“无痕模式正常,正常模式异常”的问题时,应首先怀疑扩展冲突。
- 不要被表面现象迷惑:一开始以为是缓存,后来以为是Service Worker,最后才锁定到扩展。每一步都要用对照实验验证。
- 多个扩展共存时,冲突可能不是“一对一”,而是“一对多”或“多对多”。需要耐心地用二分法、成对测试法逐步缩小范围。
- WordPress的前端代码依赖于老旧JS库,容易与现代浏览器扩展产生冲突。希望未来WordPress能升级其媒体库脚本,减少对外部全局变量的依赖。
希望这篇文章能帮助到遇到同样问题的WordPress用户。如果你也有类似的“特色图片点击无反应”故障,不妨先试试禁用所有扩展,看看是否是扩展冲突。如果是,按照本文的方法逐步定位即可。
附:我使用的扩展版本(供参考)
- UniSat Wallet: 最新版
- MetaMask: 最新版
- Phantom: 最新版
- Chrome: 稳定版(版本号略)