Browser Extension Dev Extra - User Script 介绍

本文最后更新于:2026年5月29日 下午

前言

在此之前的基础教程系列中,为了演示创建了多个 Chrome 扩展程序,它们通常都比较简单。所以在本章,我将说明扩展之外另一种允许用户修改网页的标准:User Script,它的基本思路非常简单,向用户浏览的网站注入自定义的一个脚本片段。但与扩展不同,使用 User Script 通常需要安装一个脚本管理器,例如

通过这类脚本管理器,可以从网站上直接安装其他人创建的 User Script,也可以自己创建需要的脚本。

User Script 结构

首先是结构,User Script 虽然只是一个 JavaScript 文本,但同样分为 Manifest 和 Code 两部分,前者使用注释完成,后者则通常包含在闭包函数中。下面这一个非常简单的示例脚本(由 Tampermonkey 创建)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 2026-04-09
// @description try to take over the world!
// @author You
// @match https://*/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==

;(function () {
'use strict'

// Your code here...
})()

可以看到,开头的注释以 // ==UserScript== 开始和 // ==/UserScript== 结尾,中间每一行的注释都以 @ 开头代表脚本的元数据,例如 @name/@version/@match/@grant 之类的,最接近官方文档的地方可能是 https://www.tampermonkey.net/documentation.php。你可能注意到 icon 是一个 datauri 图标。是的,由于只有一个 JavaScript 脚本,所以无法放置 icon 文件之类的。

而下面的代码使用了一个看上去有点奇怪的写法,这是在 ES6 之前为了避免全局变量污染而遗留下来的历史包袱。例如如果在 devtools console 中输入两次下面这个代码,将会出现不同的打印结果

1
2
3
4
console.log(a) // undefined
var a = 1
console.log(a) // 1
var a = 1

如果使用闭包包裹,则两次执行的变量都是局部的,不会互相影响。

1
2
3
4
5
6
7
8
9
10
;(function () {
'use strict'
console.log(a) // undefined
var a = 1
})()
;(function () {
'use strict'
console.log(a) // undefined
var a = 1
})()

重写之前的扩展

对于之前 Browser Extension Dev - 01. 介绍基本概念 创建的那个隐藏 Google 搜索主页上 AI Mode 按钮的扩展,完全可以使用 User Script 重写它。

之前的 manifest.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"manifest_version": 3,
"name": "Hide AI Mode on Google Search",
"version": "0.0.1",
"description": "Hide the AI Mode button on Google Search pages.",
"content_scripts": [
{
"matches": ["https://www.google.com/"],
"js": ["content-scripts/content.js"],
"run_at": "document_start"
}
],
"icons": {
"128": "icon/128.png"
}
}

转换成 User Script 就变成了

1
2
3
4
5
6
7
8
9
10
11
// ==UserScript==
// @name Hide AI Mode on Google Search
// @namespace https://rxliuli.com/
// @version 0.0.1
// @description Hide the AI Mode button on Google Search pages.
// @author rxliuli
// @match https://www.google.com/
// @icon https://www.google.com/s2/favicons?sz=64&domain=google.com
// @run-at document-start
// @grant none
// ==/UserScript==

然后将之前的 content-scripts/content.js 追加到闭包函数中。

1
2
3
4
5
6
7
8
;(function () {
'use strict'

const style = document.createElement('style')
style.textContent =
'button:has([d="M15.65 11.58c.18-.5.27-1.03.31-1.58h-2c-.1 1.03-.51 1.93-1.27 2.69-.88.87-1.94 1.31-3.19 1.31C7.03 14 5 12.07 5 9.5 5 7.03 6.93 5 9.5 5c.46 0 .89.08 1.3.2l1.56-1.56C11.5 3.22 10.55 3 9.5 3 5.85 3 3 5.85 3 9.5S5.85 16 9.5 16c.56 0 2.26-.06 3.8-1.3l6.3 6.3 1.4-1.4-6.3-6.3c.4-.5.72-1.08.95-1.72z"]) { display: none; }'
document.documentElement.appendChild(style)
})()

在 Tampermonkey 中安装脚本

现在,我们可以在 Tampermonkey 脚本管理器中安装脚本了。

首先从 Chrome Web Store 中安装 Tampermonkey https://chromewebstore.google.com/detail/dhdgffkkebhmkfjojejmpbldmpobfkfo

1775697649183.jpg

安装之后还必须启用 Developer Mode 并且在 Tampermonkey 扩展的设置中允许 User Scripts。

1775697452427.jpg

然后打开 chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/options.html#nav=new-user-script+editor 创建一个新的脚本

1775697776386.jpg

最后,将上面的脚本粘贴进去,然后保存。

1775697819185.jpg

现在,可以看到 AI Mode 搜索按钮确实被隐藏起来了。

1775697832818.jpg

使用 GM API

上面我们完成了一个最简单的脚本,但完全没有涉及到 UserScript 提供的独特的 GM API。目前而言,Tampermonkey 包含了相当多的 API https://www.tampermonkey.net/documentation.php

1775694780786.jpg

最常见的可能是 GM_setValue/GM_getValue,它们是扩展向脚本提供的 KV 存储 API。这里使用 GM_registerMenuCommand 注册一个菜单项来演示如何在脚本内部启用和禁用。

首先仍然需要使用 // @grant 声明权限

1
2
3
4
5
6
7
8
9
10
11
12
13
// ==UserScript==
// @name Hide AI Mode on Google Search
// @namespace https://rxliuli.com/
// @version 0.0.1
// @description Hide the AI Mode button on Google Search pages.
// @author rxliuli
// @match https://www.google.com/
// @icon https://www.google.com/s2/favicons?sz=64&domain=google.com
// @run-at document-start
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// ==/UserScript==

然后根据设置动态注册菜单项,并且在启用时自动隐藏 AI Mode 按钮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
;(function () {
'use strict'

let menuId
if (GM_getValue('visible')) {
menuId = GM_registerMenuCommand('Hide AI Mode', toggle)
} else {
menuId = GM_registerMenuCommand('Show AI Mode', toggle)
hide()
}

function toggle() {
if (GM_getValue('visible')) {
hide()
GM_registerMenuCommand('Show AI Mode', toggle, { id: menuId })
GM_setValue('visible', false)
} else {
show()
GM_registerMenuCommand('Hide AI Mode', toggle, { id: menuId })
GM_setValue('visible', true)
}
}

function hide() {
const style = document.createElement('style')
style.id = 'hide-ai-mode-on-google-search'
style.textContent =
'button:has([d="M15.65 11.58c.18-.5.27-1.03.31-1.58h-2c-.1 1.03-.51 1.93-1.27 2.69-.88.87-1.94 1.31-3.19 1.31C7.03 14 5 12.07 5 9.5 5 7.03 6.93 5 9.5 5c.46 0 .89.08 1.3.2l1.56-1.56C11.5 3.22 10.55 3 9.5 3 5.85 3 3 5.85 3 9.5S5.85 16 9.5 16c.56 0 2.26-.06 3.8-1.3l6.3 6.3 1.4-1.4-6.3-6.3c.4-.5.72-1.08.95-1.72z"]) { display: none; }'
document.documentElement.appendChild(style)
}
function show() {
document.getElementById('hide-ai-mode-on-google-search')?.remove()
}
})()

现在打开 Tampermonkey 的 Popup 的弹窗就可以看到注册的菜单项了。

1775697581036.jpg

总结

总体来说,如果你需要快速向网页注入一些脚本(这本质上就是用户脚本的定义),你可以优先使用 UserScript。如果你需要更强大的功能,比如操作标签页、运行后台定时任务,或者需要包含大型资源文件(例如 wasm,直接将 base64 嵌入内容脚本会很乱),那么你可以选择扩展。

UserScript 有几个显著的优势:

  1. 没有审核,这意味着你可以为 YouTube 添加视频下载功能,而谷歌禁止所有试图这样做的扩展程序,甚至本地下载工具 FDM 也收到了投诉。https://www.wilderssecurity.com/threads/free-download-manager-removes-support-for-youtube-downloads.441430/
  2. 更广泛的可用性,扩展在移动浏览器中难以使用,只有少数浏览器支持扩展,而支持用户脚本的浏览器数量要更多,例如 Firefox Android、Kiwi Browser、Safari + Userscripts app 等
  3. 没有数量限制,这可能是许多人不知道的,Chrome 网上应用店限制一个账户最多提交 20 个扩展程序,这是一个不常见的限制,但它确实存在。https://developer.chrome.com/docs/webstore/publish#:~:text=Note%3A%20You%20cannot%20have%20more%20than%2020%20extensions%20published%20on%20the%20Chrome%20Web%20Store
  4. 风险相对更低,扩展拥有的能力远超 UserScript,但这也意味着风险更高,例如加密货币领域因恶意扩展损失数百万美元的例子屡见不鲜。https://thehackernews.com/2025/12/trust-wallet-chrome-extension-bug.html

除了拥有更强大的 API 之外,扩展还有几个优势

  1. 可发现性,如果你希望被更多人看到,选择扩展可能是更好的选择。扩展有官方的 Chrome Web Store 或 App Store,而 User Script 没有什么“官方”商店,Userscript.Zone 是一个好的搜索工具,但并不负责审核。
  2. 可货币化,扩展尽管成功货币化的例子并不多(相比于 App/Web),但仍然存在。很难说服别人为一个脚本付费,尽管有点愚蠢,但脚本小子的刻板印象也存在
  3. UserScript 需求更加“下沉”和“长尾”,相对而言,User Script 的创建门槛足够低,并且缺乏审核或规范,所以你能找到各种形形色色的脚本和开发者,容易被灰黑产滥用
  4. 资源限制更高,例如通过嵌入 wasm/onnx 可以运行一些客户端 AI 模型,例如实现网页内容过滤或是图片识别等等,拓宽了 User Script 难以触及的可能性

Browser Extension Dev Extra - User Script 介绍
https://blog.rxliuli.com/p/09fc3bafde0b452097958b796622d031/
作者
rxliuli
发布于
2026年1月15日
许可协议