Chrome插件开发:从零开始了解Chrome Extension
Chrome Extension官方开发文档:developer.chrome.com/docs/extens…
什么是Chrome Extension
首先给出一些官方定义和解释:
官方定义:Chrome 扩展程序可通过自定义界面、监控浏览器事件和修改网页来提升浏览体验。
如何构建:您可以使用创建 Web 应用时所用的 Web 技术构建扩展程序:HTML、CSS 和 JavaScript
可以做些什么:除了 Web API 之外,扩展程序还可以使用 Chrome 扩展程序 API 来执行不同的任务
综上,我觉得Chrome Extension其实就是一个由 HTML、CSS、JavaScript 和配置文件组成的包,通过Chrome 的扩展 API 与浏览器深度交互,完成一些正常web页面不能完成的功能,比如操作浏览器界面、后台任务处理,以及一些硬件交互等,所以能做什么,不能做什么,都是是扩展API决定的
基本组成结构
一个典型 Chrome 扩展包含以下核心组件:
-
manifest.json
:配置文件,定义扩展名称、版本、权限、资源路径等。 - 内容脚本(Content Scripts) :注入到网页中的脚本,可直接操作 DOM。
- 后台脚本(Background Scripts) :独立于页面的 JavaScript 环境,用于处理全局逻辑。
- 用户界面组件:如弹出页(Popup)、选项页(Options Page)、侧边栏等。
- 静态资源:图标、图片、样式表等。
以上只有manifest.json
文件是必须的,当然插件的图标也是要提供的,算半必须吧,后面这些组成都会详细介绍,这里了解一下就好
Manifest V3 与 V2 的主要区别
其实我觉得能点进来看这篇文章的人,没有必要去详细了解V2,因为V3 是当前强制要求的最新版本(自 2023 年起新扩展必须使用 V3),所以V2相当于已经被淘汰了,但是毕竟没有过去很久,可能有一些项目需要做一些迁移,还是给大家介绍一下,后面也会专门出一篇迁移的文章
manifest.json
文件其实是Extension的“身份证”和“说明书”,决定了Extension如何与浏览器交互。不同版本的 Manifest 对应不同的 API 和权限规则。那又为什么放弃V2,需要V3呢?
首先得说说V2存在的问题,在V2版本存续期间,Chrome Extension生态长期面临两大问题:
- 安全风险:恶意Extension滥用权限,窃取用户数据
- 性能损耗:常驻后台脚本导致内存占用过高,性能损耗过于严重
Manifest V3 的变革本质是浏览器厂商对扩展生态的一次“技术纠偏”,其核心目标是通过限制自由度换取更高的安全性和性能。
V3版本又是怎么解决问题的呢?
- 资源效率:优化后台任务的生命周期管理
- 最小权限模型:限制Extension的过度权限申请
- 代码可信性:禁止远程代码动态执行
接下来,详细说说V2→V3究竟有哪些核心变革
1. 后台脚本的颠覆:Service Worker 取代 Background Pages
-
V2 的 Background Pages
本质是一个常驻内存的隐藏页面,通过
background.html
和background.js
运行,即使无页面活动也可持续执行代码,只要扩展安装后,就会持续运行,直至浏览器关闭或扩展被禁用典型问题
// V2 示例:常驻后台监听消息 chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { // 长期占用内存的逻辑 });
-
V3 的 Service Worker
改用 Service Worker 作为后台脚本载体,其生命周期由浏览器严格管理:
- 无持久化运行:仅在需要时激活(如收到事件、定时任务触发)。
- 无 DOM 访问权限:无法操作页面元素。
- 内存限制:执行完成后会被终止以节省资源。
开发者影响:需重构后台逻辑,避免依赖长时运行的任务,改用事件驱动模式。
2. 权限模型收紧
网络请求处理
V2:通过 chrome.webRequest
API 动态拦截和修改请求
// V2 动态广告拦截示例
chrome.webRequest.onBeforeRequest.addListener(
(details) => ({ cancel: details.url.includes("adserver.com") }),
{ urls: ["<all_urls>"] },
["blocking"]
);
V3:改用 Declarative Net Request 静态规则
// manifest.json 中声明规则文件
"declarative_net_request": {
"rule_resources": [{
"id": "block_ads",
"enabled": true,
"path": "rules.json"
}]
}
// rules.json 定义静态规则
[{
"id": 1,
"priority": 1,
"action": { "type": "block" },
"condition": {
"urlFilter": "||adserver.com^",
"resourceTypes": ["script"]
}
}]
权限声明收紧
V2:允许运行时动态申请权限
chrome.permissions.request({ permissions: ["tabs"] });
V3:所有权限必须在 manifest.json
中预声明,无法动态添加
{
"permissions": ["activeTab", "scripting"],
"optional_permissions": ["downloads"] // 仅部分权限可动态请求
}
开发者影响:需提前规划权限需求,放弃动态注入远程脚本的“偷懒”方案。
3. 安全策略:代码可信性与执行限制
禁止远程代码
V2:允许通过 eval()
或远程加载脚本
// V2 中动态执行远程代码(高风险!)
fetch("https://example.com/code.js")
.then(response => response.text())
.then(code => eval(code));
V3:所有逻辑必须打包至扩展本地,禁止以下操作
-
eval()
、new Function()
- 动态插入
<script>
标签加载远程 JS。 - 使用
chrome.scripting.executeScript
执行远程代码。
内容安全策略(CSP)强化
V2:允许宽松策略
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
V3:强制禁用 unsafe-eval
和内联脚本
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
}
Chrome Extension开发和一般网页开发
Extension的开发语言就是前端中大家都会接触的HTML、CSS和JavaScript,那这两者究竟有什么区别呢
1. 运行环境与执行上下文差异
Chrome Extension | 普通网页 | |
---|---|---|
执行上下文 | 多环境并行: - 内容脚本(Content Scripts) - Service Worker(后台脚本) - 弹出页(Popup)、选项页等 | 单一页面上下文: 所有代码在页面 DOM 环境中运行 |
DOM 访问权限 | 内容脚本可直接操作页面 DOM,但和页面原始脚本隔离(独立 JS 环境) | 直接操作当前页面的 DOM |
浏览器 API 访问 | 可调用 Chrome 扩展专属 API(如 chrome.tabs 、chrome.storage ) |
仅限 Web 标准 API(如 fetch 、localStorage ) |
跨域请求限制 | 可通过声明权限(如 "<all_urls>" )绕过同源策略 |
严格受同源策略限制,需依赖 CORS 或代理服务 |
生命周期管理 | Service Worker 按需激活,浏览器控制其启停 | 页面关闭即终止所有逻辑 |
2. 架构设计差异
Chrome Extension | 普通网页 | |
---|---|---|
代码组织 | 多文件协同: - manifest.json 配置文件 - 内容脚本、Service Worker、UI 组件分离 |
通常集中在单页应用(SPA)或传统多页面架构 |
通信机制 | 依赖 chrome.runtime API 实现不同组件间通信: - sendMessage - connect
|
基于 window.postMessage 或自定义事件总线 |
状态管理 | 需跨组件同步状态(如使用 chrome.storage 持久化) |
可通过 Redux、Context API 等前端框架管理 |
3. 异步编程与事件驱动差异
Chrome API 几乎全部以异步形式提供(回调或 Promise),需处理多组件协作的异步逻辑;一般网页开发异步操作集中在数据请求(如 fetch
)和用户交互事件,架构相对简单
4. 权限模型差异
Chrome Extension | 普通网页 | |
---|---|---|
权限范围 | 可申请浏览器底层权限: - 访问所有网站内容 - 管理下载、书签、历史记录等 | 仅限用户交互授权: - 地理位置 - 摄像头/麦克风 - 通知权限等 |
权限申请方式 | 必须在 manifest.json 中静态声明(Manifest V3 限制动态申请) |
可通过 Permissions API 动态请求(如 navigator.permissions.request() ) |
安全审查强度 | 上架需通过 Chrome 商店严格审核(代码扫描 + 人工复核) | 部署在自有服务器,无强制审核(依赖用户信任) |
5. 安全策略差异
Chrome Extension | 普通网页 | |
---|---|---|
内容安全策略(CSP) | 强制严格策略: - 禁止内联脚本(如 onclick="..." ) - 禁止 eval()
|
可自由定义 CSP(如允许内联脚本) |
代码来源限制 | 所有逻辑必须打包在扩展内,禁止远程代码执行(Manifest V3) | 可自由加载外部 CDN 资源(如 <script src="https://cdn.example.com/lib.js"> ) |
沙箱隔离 | 内容脚本与页面脚本隔离(无法直接共享变量) | 所有脚本共享同一全局环境 |
6. 调试与部署差异
Chrome Extension | 普通网页 | |
---|---|---|
调试环境 | 需分别调试多个组件: - Service Worker(通过 chrome://serviceworker-internals ) - 内容脚本(在网页开发者工具中) - 弹出页(独立窗口) |
单一页面调试(浏览器开发者工具) |
热重载支持 | 无原生热重载,需手动刷新扩展或使用第三方工具(如 webpack-chrome-extension-reloader ) |
主流框架(如 React、Vue)支持热重载 |
错误追踪 | 错误分散在多个上下文,需结合 chrome://extensions 的日志和浏览器控制台 |
所有错误集中在页面控制台 |
打包方式 | 必须压缩为 ZIP 文件(不含根目录),依赖 manifest.json 定义结构 |
无强制打包格式,通常直接部署 HTML/CSS/JS 文件或使用构建工具(如 Webpack)打包 |
发布流程 | 必须提交至 Chrome 网上应用店,通过审核后发布(1-7 天) | 直接部署到服务器或 CDN,实时生效 |
版本更新 | 用户自动接收更新,但需重新审核新版本 | 用户访问时立即获取最新版本(可能受缓存影响) |
以上差不多就是宏观上的一些了解了,打个预告,下一篇文章会介绍环境搭建,完成经典的“Hello World”,同时介绍基本的本地加载与开发调试技巧