1. 这条提示到底在说什么
如果你最近打开浏览器,发现 Tampermonkey 的图标上冒出一个红色感叹号,点开之后弹出一段中英混杂的提示——“请启用开发者模式以允许用户脚本注入,点击这里了解如何操作。Please enable developer mode to allow userscript injection”——那你不是一个人。这个提示从 Chrome 浏览器 120 版本之后开始大规模出现,Edge 也在相近的时间点跟进了同样的策略。简单说,浏览器厂商收紧了扩展程序的权限边界,Tampermonkey 这类需要往网页里“注入代码”的扩展,必须由用户手动打开一个叫“开发者模式”的开关,才能继续正常工作。
这件事的本质是什么?Tampermonkey(中文圈习惯叫“篡改猴”)是一个用户脚本管理器。它本身不干活,干活的是你装的那些脚本——比如网课自动签到、网页去广告、批量抓取表单数据、给某个网站加个暗色主题。这些脚本要生效,就必须被“注入”到目标网页的运行环境里,跟网页原本的代码一起跑。浏览器出于安全考虑,默认不允许扩展随便往页面里塞代码,因为这也是恶意扩展常用的手法。所以厂商加了一道闸:你想注入,就得显式打开开发者模式,等于你亲手签了个“我知道我在干什么”的确认书。
适合看这篇内容的人很明确:日常依赖 Tampermonkey 跑脚本的重度用户、做前端调试需要临时注入代码的开发者、以及被这个提示卡住导致脚本“已启用但不运行”的普通用户。不管你是 Chrome 还是 Edge,不管你用的是 Windows、macOS 还是 Linux,处理思路是一致的,只是入口位置略有差别。下面我把这件事从原理到操作、从排查到避坑,完整地捋一遍。
2. 为什么浏览器要逼你开开发者模式
2.1 用户脚本注入的底层机制
要理解这个提示,得先知道用户脚本是怎么跑起来的。Tampermonkey 的工作模式可以拆成三步:拦截、匹配、注入。当你在地址栏输入一个网址、页面开始加载时,Tampermonkey 会先看一眼当前 URL,跟你脚本里写的@match或@include规则做比对。匹配上了,它就把脚本内容通过浏览器提供的扩展接口,塞进这个页面的执行上下文里。塞进去的时机很关键——有的脚本要在页面 DOM 构建之前就跑(@run-at document-start),有的要等页面加载完(@run-at document-idle),时机不对脚本就会失效。
这个“塞进去”的动作,专业叫法是脚本注入。浏览器内核(Chromium 系)对扩展的能力是分级的。普通扩展只能操作自己的弹窗、读写有限的存储、发发网络请求。而注入脚本意味着扩展能读写目标页面的 DOM、能拿到页面的 cookie 上下文、能改表单提交的内容——权限一下子大了一圈。早些年这个权限是默认给的,只要用户装了扩展就默认信任。后来恶意扩展泛滥,厂商就开始收紧,把“注入”归到了需要用户显式授权的范畴,开发者模式就是那个授权开关。
2.2 开发者模式这道闸的真实作用
很多人误以为开发者模式是给“开发扩展的人”用的,跟自己没关系。其实在 Chromium 的权限模型里,开发者模式是一个总开关,打开它等于告诉浏览器:“我信任我手动加载的这些扩展,愿意承担相应风险。”它主要放开三件事:允许加载未打包的扩展、允许扩展使用更高权限的接口、允许扩展往页面注入脚本。Tampermonkey 需要的正是第三项。
这里有个容易混淆的点:Tampermonkey 是从应用商店正常安装的,不是“未打包扩展”,为什么还要开发者模式?原因是厂商把“脚本注入”这个高危能力单独拎了出来,跟扩展是否来自商店无关,只跟用户是否显式授权有关。所以你会看到一个有点反直觉的现象——商店里装的扩展,照样要你开开发者模式。这不是 Tampermonkey 的 bug,是浏览器策略变更后的必然结果。
注意:开发者模式打开后,浏览器每次启动可能会弹一个“请停用以开发者模式运行的扩展程序”的提示条。这是 Chromium 的固有行为,不是中毒,也不是扩展有问题。后面我会讲怎么处理这个提示条。
2.3 不开会怎样:脚本“已启用但不运行”
不开开发者模式,最典型的表现就是热词里提到的“篡改猴脚本已启用但是没有运行”。你在 Tampermonkey 的管理面板里看,脚本明明是启用状态,图标也是彩色的,但打开目标网站,脚本该干的事一件没干。打开控制台(F12)看,可能连脚本的日志都没有,或者报一个权限相关的错误。这时候很多人会反复重装脚本、重装扩展、甚至重装浏览器,其实方向全错了——问题不在脚本,在浏览器的那道闸没开。
还有一种更隐蔽的情况:部分脚本能跑,部分不能。这通常是因为能跑的脚本用的是@grant none模式(直接在页面上下文跑,不调用扩展特权接口),不能跑的用了GM_setValue、GM_xmlhttpRequest这类需要扩展特权的接口。开发者模式没开,特权接口被拦,脚本自然就哑了。所以判断标准很简单:只要你的脚本用到了 GM_ 开头的接口,就必须开开发者模式。
3. Chrome 和 Edge 的具体操作步骤
3.1 Chrome 浏览器开启路径
Chrome 的操作入口在扩展管理页。最直接的方式是在地址栏输入chrome://extensions/回车,进入扩展管理界面。这个页面右上角有一个“开发者模式”的开关,把它拨到打开状态。开关打开后,页面顶部可能会多出一排按钮(加载已解压的扩展程序、打包扩展程序等),这些你不用管,它们只是开发者模式的附带功能。
打开之后,回到 Tampermonkey 的弹窗,那个红色感叹号提示应该就消失了。如果没消失,点一下 Tampermonkey 图标里的“重新加载”或者干脆刷新一下目标网页。实测下来,绝大多数情况刷新页面就能恢复。这里有个细节:开发者模式开关是全局的,打开一次就行,不需要每个扩展单独设置。但如果你用的是 Chrome 的企业策略版本或者被组织管理的设备,这个开关可能被管理员锁死,那就得找 IT 处理了。
3.2 Edge 浏览器的差异点
Edge 的操作逻辑跟 Chrome 几乎一样,入口是edge://extensions/。打开后左侧栏或者页面底部(取决于 Edge 版本)能找到“开发人员模式”的开关。Edge 把这个开关藏得比 Chrome 稍微深一点,有些版本需要先点左下角的“详细信息”才能看到。热词里“edge开发者模式使用”搜索量高,就是因为不少人第一次找不到入口。
Edge 还有一个自己的特点:它对扩展的权限管理比 Chrome 更细,有时候开了开发人员模式,还会额外弹一个“此扩展可以读取和更改你访问的网站上的所有数据”的确认框,需要你点“允许”。这个框不是每次都弹,通常在你新装扩展或者扩展更新后第一次运行时出现。看到就点允许,别犹豫,否则脚本照样不跑。
3.3 操作后的验证方法
开完开关别急着关页面,做个验证。随便打开一个你装了脚本的网站,按 F12 打开开发者工具,切到 Console 面板。如果你的脚本有输出日志(很多脚本会在启动时打印一行版本信息),能看到就说明注入成功了。看不到日志的话,可以在 Console 里手动敲一行typeof GM_info,如果返回"object",说明 Tampermonkey 的特权接口已经可用,注入通道是通的。返回"undefined"就说明还没生效,回去检查开关状态。
另一个验证角度是看 Tampermonkey 的弹窗。正常工作时,弹窗里会列出当前页面匹配到的脚本,每个脚本前面有个小圆点,绿色代表正在运行。如果圆点是灰色或者脚本压根没出现在列表里,那就是匹配规则或者注入权限的问题。这个面板是排查脚本问题最常用的入口,建议养成习惯,脚本不跑先看这里。
4. 那些让人抓狂的连带问题
4.1 开发者模式提示条怎么处理
开了开发者模式之后,Chrome 每次启动会在顶部弹一条“请停用以开发者模式运行的扩展程序”的提示。这条提示很烦,但它不影响功能,点右边的叉关掉就行。如果你实在受不了,有几个思路:一是用组策略或者注册表把这条提示屏蔽掉(网上有现成的注册表脚本,原理是改 Chromium 的一个策略键值),二是换用 Edge,Edge 对这条提示的处理相对温和,有些版本不弹。不过我得说句实话,为了省一次点击去改注册表,性价比不高,而且系统更新后可能失效,我个人的做法就是每次点叉,习惯了也就那样。
4.2 脚本装了但列表里不显示
这种情况通常是匹配规则的问题,跟开发者模式无关。Tampermonkey 判断脚本是否对当前页面生效,靠的是脚本头部的@match、@include、@exclude这几行元数据。如果 URL 不匹配,脚本就不会出现在弹窗列表里。排查方法是打开 Tampermonkey 的管理面板,找到那个脚本,看它的匹配规则写的是什么。比如规则写的是https://example.com/*,而你访问的是http://example.com(少了 s),那就匹配不上。改规则或者用@match *://example.com/*这种通配写法都能解决。
还有一种情况是脚本被“排除”了。Tampermonkey 支持在设置里配置全局排除规则,或者脚本自己写了@exclude。检查一下设置页的“排除”列表,看看目标网站是不是被误加了进去。这个坑我踩过,当时排查了半小时才发现是自己之前手滑加了个排除规则。
4.3 权限被浏览器策略拦截
企业环境或者用了某些安全软件的电脑上,即使开了开发者模式,脚本注入还是可能被拦。表现是 Console 里报一个Refused to execute inline script或者Content Security Policy相关的错误。这是目标网站自己的 CSP 策略在起作用,跟浏览器和 Tampermonkey 都没关系。CSP 是网站用来防 XSS 攻击的,它会限制哪些来源的脚本能执行。Tampermonkey 的注入方式在某些严格 CSP 的网站上会被挡。
应对办法是让脚本用@grant声明特权接口,通过 Tampermonkey 的沙箱环境跑,而不是直接注入页面上下文。具体来说,把脚本头部的@grant none改成@grant GM_setValue之类的具体接口,Tampermonkey 就会用隔离环境执行,绕过 CSP。代价是脚本里不能直接访问页面的全局变量了,需要额外处理。这个属于进阶话题,普通用户遇到 CSP 拦截的概率不高,知道有这么回事就行。
5. 脚本注入的进阶理解与选型
5.1 注入时机对脚本行为的影响
@run-at这个元数据决定了脚本什么时候注入,选错了脚本行为会完全不一样。document-start是最早的时机,页面 DOM 还没建好,适合做请求拦截、修改页面初始配置这类操作。document-end是 DOM 建好但资源可能还没加载完,适合操作 DOM 元素。document-idle是默认值,等页面基本加载完再跑,最稳妥但可能错过一些早期事件。
我见过不少人写脚本时无脑用默认值,结果要拦截的请求早就发出去了,脚本才启动,自然拦不住。判断方法很简单:如果你的脚本要改的是页面加载时就确定的东西(比如某个全局配置对象),用document-start;如果要操作的是页面上看得见的元素,用document-end或document-idle。Tampermonkey 的文档里对这几个时机有详细说明,值得花十分钟读一遍。
5.2 GM 接口的能力边界
Tampermonkey 提供了一组GM_开头的接口,这是它区别于普通书签脚本的核心价值。常用的几个:GM_setValue/GM_getValue做跨页面持久化存储,GM_xmlhttpRequest发跨域请求(绕过同源策略),GM_addStyle往页面加 CSS,GM_registerMenuCommand在 Tampermonkey 菜单里加自定义命令。这些接口都需要开发者模式授权才能用。
这里有个选型经验:能用原生fetch解决的,就别用GM_xmlhttpRequest,因为后者虽然能跨域,但错误处理和调试都比原生麻烦。只有在确实需要跨域、且目标服务器不允许 CORS 的情况下,才动用 GM 接口。另外GM_setValue存的数据是跟脚本绑定的,换脚本或者改脚本名可能导致数据读不到,重要数据建议同时做一份导出备份。
5.3 脚本来源与安全考量
用户脚本的生态是开放的,网上有大量现成的脚本可以直接装。但开放也意味着风险——脚本能读写你访问的页面,理论上能拿到你在页面上的所有操作,包括登录态。装脚本前至少看一眼脚本头部的@match范围,如果它匹配的是*://*/*(所有网站),就要多留个心眼。正经的脚本通常只匹配它需要的那几个域名。
我的习惯是:装之前先看脚本的更新时间和评价,太老或者没人维护的慎用;装之后在 Tampermonkey 面板里看一眼它的权限声明,用不到的权限可以手动关掉。Tampermonkey 本身也提供了脚本沙箱和权限控制,合理利用能降低风险。这不是危言耸听,而是这个生态里真实存在的坑,谨慎一点没坏处。
6. 常见问题速查与避坑心得
6.1 问题排查速查表
| 现象 | 最可能的原因 | 处理方式 |
|---|---|---|
| 提示启用开发者模式 | 浏览器策略收紧,注入权限未授权 | 打开扩展管理页的开发者模式开关 |
| 脚本已启用但不运行 | 开发者模式未开,或匹配规则不命中 | 先开开关,再检查@match规则 |
| 部分脚本跑部分不跑 | 用了 GM 接口的脚本被拦 | 开开发者模式,确认@grant声明 |
| 弹窗列表里没有脚本 | URL 不匹配或被排除规则命中 | 检查匹配规则和排除列表 |
| Console 报 CSP 错误 | 目标网站 CSP 拦截直接注入 | 改用 GM 接口走沙箱执行 |
| 每次启动弹提示条 | 开发者模式的固有行为 | 手动关闭,或用策略屏蔽 |
6.2 几个我踩过的坑
第一个坑是“以为开了开发者模式就万事大吉”。实际上开发者模式只是必要条件,不是充分条件。脚本能不能跑,还取决于匹配规则、注入时机、CSP 策略、脚本本身的代码质量。我遇到过开了开关脚本还是不跑的情况,最后发现是脚本里有个语法错误,Tampermonkey 静默失败了,Console 里才有报错。所以排查脚本问题,F12 的 Console 面板永远是第一站。
第二个坑是“频繁切换开发者模式”。有些人为了消掉提示条,用完脚本就把开关关掉,下次用再打开。这样折腾几次之后,Tampermonkey 的状态可能会错乱,表现为脚本列表加载不出来或者设置丢失。我的建议是开关就让它开着,提示条点叉关掉,别反复横跳。Tampermonkey 的设置是存在浏览器本地存储里的,频繁切换开关理论上不影响,但实测确实有人遇到过状态异常,重装扩展才恢复。
第三个坑是“脚本冲突”。同一个页面上装了两个脚本,都往页面里加元素或者改同一个 DOM 节点,结果互相覆盖,表现为时好时坏。排查方法是把脚本一个个禁用,二分法定位。Tampermonkey 面板里可以单独禁用某个脚本,不用卸载,很方便。定位到冲突的两个脚本后,看能不能改匹配范围让它们错开,或者调整@run-at时机让它们按顺序执行。
6.3 给长期使用者的建议
如果你把 Tampermonkey 当生产力工具用,建议做两件事。一是定期导出脚本备份,Tampermonkey 的设置页有导出功能,导出一个 zip 文件,里面包含所有脚本和配置。浏览器重装或者换电脑时,导入就能恢复,省得一个个重装。二是给重要脚本加版本注释,脚本头部写清楚用途、作者、更新日期,时间长了脚本多了,光看名字根本想不起来是干嘛的。
另外,浏览器大版本更新后,建议主动检查一下 Tampermonkey 是否正常工作。Chromium 系的权限策略还在持续调整,说不定哪个版本又改了规则。Tampermonkey 的更新通常跟得比较紧,保持扩展自动更新打开,能省不少事。我个人的习惯是每次浏览器大版本更新后,随便打开一个常用脚本的网站,确认一下脚本还在跑,花不了一分钟,但能避免关键时刻掉链子。
最后分享一个判断脚本是否真的在运行的小技巧:在 Tampermonkey 的设置里打开“显示脚本运行状态”,这样脚本执行时图标上会有个短暂的动画或者角标。比翻 Console 快,适合日常快速确认。这个选项在设置页的“通用”里,找一下就有。