Browser Extension Dev - 06. 按需注入脚本
本文最后更新于:2026年1月26日 凌晨
前言
在上一章 Browser Extension Dev - 05. Storage and Configuration 中,我们介绍了为扩展添加设置页面并使用 Storage API 保存和读取配置的功能。在这一章,我们将介绍按需注入脚本。这种方式完全不会拖慢网站运行速度,同时在 Chrome Web Store 安装时不会有任何安全警告提示。接下来我们将实现一个扩展:点击图标即可将网页主要内容复制为 Markdown。
思考
我们之前已经接触过 Content Script 注入和 Background Script 监听扩展图标点击。虽然尚未介绍,但两者可以进行消息通信。
有了上面的背景知识,你可能会想要这样做:
- 为所有网页注入 Content Script 并监听后台消息
- 点击扩展图标时在 Background Script 通知 Content Script
- 在 Content Script 中执行具体逻辑
这种方法有几个主要缺点:
- 默认为所有网页注入 Content Script 不仅会拖慢网站速度,还可能导致风险,因为注入过程对用户完全无感知,后续扩展更新可能引入漏洞
- 权限要求极高,安装扩展时会提示安全警告,说明这个扩展要求读取和修改所有用户访问的网站

而对于需要明确动作触发的场景,其实有更简单的实现方式:
- 点击扩展图标时在 Background Script 中向当前网页注入一段脚本
- 在脚本中执行具体逻辑
这样,需要的权限就从 ['<all_urls>'] 变成了 ['activeTab', 'scripting'],虽然权限数量变多了,但风险反而更低,必须由用户触发才能执行代码,所以安装扩展时不会有任何警告。例如:

这里涉及到的关键 API 是 scripting.executeScript,顾名思义,用于执行自定义脚本。
参考 Chrome 官方 activeTab 指南:https://developer.chrome.com/docs/extensions/develop/concepts/activeTab
实现
在扩展图标点击时注入脚本
接下来在后台脚本中实现监听和注入部分。
首先还是更新 wxt.config.ts,添加所需权限以及空的 action 字段。
1 | |
然后添加一个用于测试的注入脚本。与 Content Script 不同,这类脚本在 WXT 中需要使用 defineUnlistedScript 声明。
1 | |
然后在 background 中监听并注入它。
1 | |
除了 files 参数,还可以通过 func/args 直接传递函数和参数,适用于简单场景。参考:https://developer.chrome.com/docs/extensions/reference/api/scripting#type-ScriptInjection
当我们打开 google.com 然后点击扩展图标时,却发现没有反应。查看扩展详情页面,可以看到一个错误。
1 | |
和之前 Browser Extension Dev - 03. 注入 UI 时一样,需要在 manifest 中增加 web_accessible_resources 配置。
1 | |
然后再试一次,可以看到脚本确实被注入并正确执行了。

⚠️ 局限性:如果你希望注入的脚本能持久化(刷新或重新进入页面后仍自动运行),这是行不通的,仍然需要正确声明
host_permissions权限来持久化注入 Content Script,即使使用 scripting API 仍然受到权限模型的限制。
在注入脚本中实现功能
接下来实现读取网页主要内容,转换为 Markdown,然后复制到剪贴板的功能。借助 npm 生态,实现起来非常简单。
- 读取网页主要内容:使用 @mozilla/readability 包
- 转换 HTML 为 Markdown:使用 turndown 包
首先安装需要的依赖
1 | |
然后编写少量胶水代码即可完成。
1 | |


总结
在本章中,我们实现了一个按需注入脚本的扩展,它不会影响网页正常运行,只在用户触发时才执行代码,真正做到即插即用。在下一篇,我们将继续完善这个扩展,使用 Popup 弹窗直接预览和编辑从当前页面复制的 Markdown。
如果有任何问题,欢迎加入 Discord 群组讨论。
https://discord.gg/VxbAqE7gj2