【Chrome-Edge-Firefox】浏览器插件开发

文章目录

  • 一、什么是浏览器插件
  • [二、快速入门:一个"Hello World"示例](#二、快速入门:一个“Hello World”示例)
    • [2.1 项目结构](#2.1 项目结构)
    • [2.2 各个文件示例和解释](#2.2 各个文件示例和解释)
    • [2.3 如何使用](#2.3 如何使用)
  • [三、WebExtensions API 核心组件详解 (Manifest V3)](#三、WebExtensions API 核心组件详解 (Manifest V3))
    • [3.1 WebExtensions API 的命名空间](#3.1 WebExtensions API 的命名空间)
    • [3.2 WebExtensions API 核心功能集合](#3.2 WebExtensions API 核心功能集合)
      • [3.21 🌐 核心浏览器功能与管理](#3.21 🌐 核心浏览器功能与管理)
      • [3.22🔌 扩展程序环境与运行时](#3.22🔌 扩展程序环境与运行时)
      • [3.23 🖥️ 用户界面交互](#3.23 🖥️ 用户界面交互)
      • [3.24 🕸️ 网络与内容交互](#3.24 🕸️ 网络与内容交互)
      • [3.25 ⚠️ 核心概念(V3 重点)](#3.25 ⚠️ 核心概念(V3 重点))
  • 四、跨浏览器扩展开发
    • [4.1 异步风格](#4.1 异步风格)
    • [4.2 使用 WebExtension Polyfill 来统一](#4.2 使用 WebExtension Polyfill 来统一)
  • 五、发布浏览器扩展

一、什么是浏览器插件

浏览器插件(Browser Extension),也常被称为扩展程序(Extension)、插件(Plugin)、附加组件(Add-on / Addon)、加载项(Add-in)、WebExtensions(标准名)等等。

浏览器插件(Extension)本质上是一组使用 HTML、CSS 和 JavaScript 编写的网页文件,它们拥有比普通网页更强大的权限,可以访问浏览器内部的 WebExtensions API,从而实现对浏览器行为或网页内容的深度修改和控制。

🧊它和JetBrains、Visual Studio系列软件里面的插件是类似的,有如下共同特点:

  • 都是依附在宿主软件里运行的可扩展功能模块
  • 都通过宿主公开的扩展 API 实现功能
  • 都有安装、激活、停用、卸载等生命周期
  • 都被权限或沙箱机制限制可访问范围
  • 都采用标准化打包方式并能在"插件商店"分发
  • 更新独立,不影响宿主本体

📌 关键术语:

  • WebExtensions:浏览器扩展开发的统一 API 标准,由 Firefox 首创,后被 Chrome、Edge 等浏览器采纳。它定义了命名空间、方法、事件等核心结构,使扩展能够跨浏览器兼容。
  • WebExtensions API:浏览器提供给扩展开发者的接口集合,可用于管理标签页、存储数据、监听事件等。简单来说,它就是操作浏览器的"工具箱"。
  • Manifest V3 (MV3) :Chrome、Edge 推荐使用的第三代扩展清单规范,重点在于安全性、性能和隐私保护,规定了扩展的权限、Service Worker 使用方式等。
  • 简单理解:WebExtensions API 是工具箱,Manifest V3 是使用工具箱时必须遵守的规则,两者共同构成现代浏览器扩展的开发基础。

前端传统三件套不必说,主要的就是WebExtensions API需要学习一下。

⏭️不多说,先来个最简单的例程体验一下吧。


二、快速入门:一个"Hello World"示例

2.1 项目结构

假设项目目录是:BrowserExtension。

最简的项目结构如下:

❗❗只有:manifest.json 必须叫这个名字,必须在根目录、必须存在。

bash 复制代码
|- BrowserExtension
   |- manifest.json  # 插件的配置文件(身份证)
   |- popup.html     # 点击图标后弹出的界面
   |- popup.js       # 弹出窗口的逻辑脚本

当然也可以复杂一点:

2.2 各个文件示例和解释

① 插件配置:manifest.json:这是插件的配置清单,指定了插件的基本信息和权限。我们遵循最新的 Manifest V3 (MV3) 规范。

json 复制代码
{
  "manifest_version": 3,
  "name": "简单的Hello World插件",
  "version": "1.0",
  "description": "一个用于演示浏览器插件基本功能的简单示例。",
  "action": {
    "default_title": "点击我!",
    "default_popup": "popup.html"
  },
  "permissions": [
    "activeTab",
    "scripting"  
  ]
}

🔓下面是对上述json内容的具体解释,注意:json并不支持注释,下面仅仅是解释代码

bash 复制代码
{
  // ============================================
  // 插件基本信息配置
  // ============================================
  
  "manifest_version": 3,           // 必须为3,表示使用Manifest V3规范
  "name": "简单的Hello World插件",  // 插件显示名称(商店中可见)
  "version": "1.0",                // 版本号,遵循语义化版本控制
  "description": "一个用于演示浏览器插件基本功能的简单示例。",  // 插件简短描述
  
  // ============================================
  // 浏览器工具栏按钮配置
  // ============================================
  
  "action": {                      // 定义工具栏按钮行为
    "default_title": "点击我!",     // 鼠标悬停时显示的提示文本
    "default_popup": "popup.html"  // 点击按钮时弹出的HTML页面
  },
  
  // ============================================
  // 权限声明(必须明确声明所需权限)
  // ============================================
  
  "permissions": [                 // 插件需要的API权限列表
    "activeTab",                   // 访问当前激活的标签页
    "scripting"                    // 允许向页面注入脚本
  ]
}

⛽JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它使用严格的文本格式来表示由字符串键特定类型值组成的结构化数据,支持嵌套序列化。核心要点:

  • 格式:基于键值对的结构化文本
  • 键:必须是双引号包裹的字符串
  • 值:仅限6种类型:字符串、数字、布尔值、null、对象、数组
  • 特性:可嵌套、可序列化、跨平台通用
  • (json里面不支持注释)

② 界面文件:popup.html,提供一个简单的按钮界面,并引入逻辑脚本。

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>Hello Extension</title>
    <meta charset="UTF-8">
    <style>
        /* 简单写个样式 */
        body {
            width: 200px;
            height: 100px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: Arial, sans-serif;
        }
        button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <button id="alertButton">点我弹窗!</button>

    <script src="popup.js"></script>
</body>
</html>

③ 逻辑脚本:popup.js,这是实现功能的关键代码。它监听按钮点击事件,并使用 WebExtensions API 向当前页面注入代码。

javascript 复制代码
// popup.js
document.addEventListener('DOMContentLoaded', function() {
    // 获取 HTML 中定义的按钮元素
    let button = document.getElementById('alertButton');
    
    // 给按钮添加点击事件监听器
    button.addEventListener('click', function() {
        // 核心功能:向当前活动标签页注入并执行一段脚本
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            // tabs[0].id 是当前活动标签页的ID
            chrome.scripting.executeScript({
                target: {tabId: tabs[0].id},
                func: showAlert // 指定要在页面中执行的函数
            });
        });
    });
});

/**
 * 这个函数将作为"内容脚本"被注入到当前网页中执行。
 * 注意:这个函数必须是自包含的,不能访问 popup.js 中的外部变量。
 */
function showAlert() {
    // 在当前网页的主上下文中执行 JavaScript 的 alert 弹窗
    alert('恭喜你,你的第一个浏览器插件运行成功了!');
    
    // 也可以执行更复杂的 DOM 操作,比如:
    // document.body.style.backgroundColor = 'lightblue';
}

2.3 如何使用

在 Chrome 浏览器中,地址栏输入并访问 chrome://extensions

鼠标点击一样的:点击扩展图标,然后设置

🟢右上角:开启 "开发者模式"

点击 "加载已解压的扩展程序",选择包含这三个文件的文件夹。

打开任意一个普通网页(非 chrome:// 开头的页面),点击工具栏上的插件图标,再点击按钮即可测试。


🟢 Chrome 内部页面(chrome:// 开头)有特殊的限制和保护机制。

  • chrome:// 页面(如 chrome://settings、chrome://extensions)是 Chrome 浏览器的内部管理页面,这些页面拥有更高的权限,可以访问浏览器核心功能,为了防止恶意插件攻击浏览器本身,Chrome 禁止插件访问这些页面。

你如果使用扩展,扩展会报错:

点击错误按钮,即可看到:

点击全部清除,即可清除错误。

三、WebExtensions API 核心组件详解 (Manifest V3)

📌 关键术语:

  • WebExtensions:浏览器扩展开发的统一 API 标准,由 Firefox 首创,后被 Chrome、Edge 等浏览器采纳。它定义了命名空间、方法、事件等核心结构,使扩展能够跨浏览器兼容。
  • WebExtensions API:浏览器提供给扩展开发者的接口集合,可用于管理标签页、存储数据、监听事件等。简单来说,它就是操作浏览器的"工具箱"。
  • Manifest V3 (MV3) :Chrome、Edge 推荐使用的第三代扩展清单规范,重点在于安全性、性能和隐私保护,规定了扩展的权限、Service Worker 使用方式等。
  • 简单理解:WebExtensions API 是工具箱,Manifest V3 是使用工具箱时必须遵守的规则,两者共同构成现代浏览器扩展的开发基础。

📗文档:https:
//developer.chrome.com/docs/extensions/get-started?hl=zh-cn

3.1 WebExtensions API 的命名空间

在编程中,命名空间(Namespace)是一种用于组织和划分代码、避免命名冲突的机制(C++和C#常见)。

在 WebExtensions API中,命名空间就是指代一系列相关联的 API 方法、属性和事件的顶级对象名称(就是全局的 chromebrowser 对象)。可以把它理解为浏览器扩展功能的不同 "功能模块"或"工具箱"**。

所有的 WebExtensions API 功能都挂在全局对象 chrome 或 browser下面。

例如:

javascript 复制代码
// tabs 是一个命名空间
chrome.tabs.query({active: true}, function(tabs) {
    console.log(tabs[0].url);
});
  • chrome 就是顶级对象,它是整个扩展 API 的入口。
  • tabs 是 chrome 下的命名空间,里面有一系列方法(query、create、update 等)和事件(onCreated、onUpdated 等)。
  • 命名空间就是 chrome 对象下的第一个子属性。
  • 调用 API 时,您需要先指定命名空间,再调用具体的方法

格式:

bash 复制代码
调用格式: chrome.[命名空间].[方法/属性/事件]

命名空间的作用:

作用 解释 示例
功能隔离 将不相关的功能划分到不同的模块,使得 API 结构清晰、易于查找和理解。 tabs 命名空间只处理标签页,bookmarks 命名空间只处理书签,它们的功能不会混淆。
权限控制 扩展程序只有在 manifest.json 中声明了相应的权限后,才能访问对应的命名空间。 声明 "permissions": ["tabs"] 才能使用 chrome.tabs 的大部分功能;未声明就无法使用。
避免冲突 确保不同的功能模块即使有相同名称的方法(例如:create),也不会互相干扰。 chrome.tabs.create 用于创建标签页;chrome.windows.create 用于创建窗口。名称相同,但功能和上下文不同。

3.2 WebExtensions API 核心功能集合

3.21 🌐 核心浏览器功能与管理

这部分 API 允许扩展程序直接操作浏览器环境,是构建大部分实用工具的基础。

命名空间(英文) Manifest V3 变化 主要修正/优化
tabs 稳定 修正:管理单个标签页的属性(URL、标题、加载状态等)和行为。
windows 稳定 修正:管理整个浏览器窗口(打开、关闭、最大化、获取焦点等)。
sessions 稳定 优化:在 Chrome 中用于管理最近关闭的标签页和窗口
bookmarks 稳定 优化:提供完整的书签 CRUD (创建、读取、更新、删除) 操作。
history 稳定 优化:访问和管理用户的浏览器访问历史记录。
downloads 稳定 优化:监听、启动、暂停和取消文件下载。

3.22🔌 扩展程序环境与运行时

这部分 API 关注扩展程序自身的生命周期、配置和内部通信。

命名空间(英文) Manifest V3 变化 主要修正/优化
runtime 核心 修正:扩展程序的生命周期安装事件版本信息长连接和一次性消息传递
storage 核心 修正:提供 local (本地)、sync (同步) 和 managed (企业管理) 三种存储区。必须用于持久化数据,因为 Service Worker 不保证持续运行。
i18n 稳定 优化:用于国际化和多语言支持。
identity 稳定 优化:实现 Chrome 或 Firefox 用户的OAuth2 授权流程

3.23 🖥️ 用户界面交互

这些 API 用于在浏览器中创建可见的、用户可交互的界面元素。

命名空间(英文) Manifest V3 变化 主要修正/优化
action 更名/核心 重要修正 :在 Manifest V3 中,browserActionpageAction 合并为 action。负责工具栏按钮、弹出窗口和徽章(Badge Text)。
contextMenus 稳定 修正:在右键上下文菜单中添加自定义项目。
notifications 稳定 修正:创建和管理桌面通知。
omnibox 稳定 修正:注册关键字,在浏览器地址栏(智能框)提供自定义建议。

3.24 🕸️ 网络与内容交互

这是扩展程序中最强大和最敏感的部分,需要更严格的权限管理。

命名空间(英文) Manifest V3 变化 主要修正/优化
webRequest 重要变化 修正 :在 Manifest V3 中,webRequest 仅能用于观察和分析 网络请求。不允许在 Service Worker 中进行同步阻断操作。
declarativeNetRequest V3 核心 重要修正 :在 Manifest V3 中,用于阻断、重定向和修改请求 ,是 webRequest 阻断功能的替代品。它使用静态规则集,效率更高,但功能更受限。
cookies 稳定 优化:获取、设置和监听 HTTP Cookies 的变化。
contentScripts 稳定 优化:是机制而非 API 命名空间 。它允许脚本在网页中运行,并使用 runtime.sendMessagetabs.sendMessage 与后台通信。

3.25 ⚠️ 核心概念(V3 重点)

概念 修正/优化
Service Worker 重要修正 :取代了 Manifest V2 中的 background.html(后台页面)。Service Worker 是基于事件驱动 的,会在不活跃一段时间后被关闭 ,因此数据必须持久化到 storage,且不支持同步操作。
主机权限 (Host Permissions) 优化:例如 <all_urls>*://*.google.com/*,用于授予扩展程序在特定 URL 上执行内容脚本或调用 API 的权限。
权限(Permissions) 优化:用于启用特定的 API 命名空间,例如 "tabs""history""webRequest" 等。

四、跨浏览器扩展开发

主流浏览器主要有 Chrome、Edge 和 Firefox。它们都基于 WebExtensions 标准开发扩展,因此绝大多数 API 兼容性良好,跨浏览器开发相对简单。

主要差别在于顶级对象和异步风格不同(实际情况更复杂,比如用户浏览器版本不同,浏览器对标准的支持情况):

浏览器 顶级对象 异步风格 风格备注
Chrome chrome 回调(callback) 原生 Chromium 风格(正转向 Promise)
Edge (Chromium) chrome / browser 回调 / Promise browser 为兼容 Firefox 提供 Promise 封装
Firefox browser / chrome Promise / 回调 官方推荐 browser 和 Promise

4.1 异步风格

同步和异步指的是代码执行的顺序和阻塞机制。

  • 同步风格(Synchronous Style,阻塞式): 代码按照编写的顺序逐行执行。当执行到某个操作时,程序会停下来等待该操作彻底完成并返回结果后,才能继续执行下一行代码。在浏览器环境中,长时间的同步操作会导致浏览器界面卡死(冻结),用户体验非常差。
  • 异步风格(Asynchronous Style,非阻塞式): 代码按照编写的顺序发起任务,但不会停下来等待。程序会立即继续执行下一行代码。当耗时的任务完成后,会通过某种机制(如回调函数callback、Promise)来通知程序并处理结果。
特性 同步风格 (Synchronous) 异步风格 (Asynchronous)
执行模式 顺序执行,逐行等待 非阻塞执行,任务发起后立即返回
程序状态 阻塞(Block) 非阻塞(Non-Block)
等待机制 必须等待当前操作完成才能继续 操作在后台进行,通过事件、回调或 Promise 等通知结果
应用场景 适用于 CPU 密集型任务,或者对时间要求不高的简单操作。 适用于 I/O 密集型任务(网络请求、文件读写、数据库操作、浏览器 API 调用等)。
用户体验 在耗时操作时,程序/界面会卡死 程序/界面保持响应,用户体验好
代码实现 直接的函数调用 (例如:const result = add(1, 2); 回调函数 (Callback)PromiseAsync/Await
浏览器扩展 API 例子 - chrome.tabs.query(...) (回调或 Promise)
主要优点 简单、易于理解和调试 充分利用资源,提高程序效率和响应性

浏览器扩展 API(如 chrome.tabs.query()browser.storage.local.get())涉及大量**输入/输出(I/O)**操作,这些操作都可能需要时间,所以它们必须设计成异步的,以防止浏览器卡死。

异步风格主要有两种代码体现方式:

🟢A. 回调函数风格(Callback Style)- 传统 Chrome 风格

这是 Chrome 扩展 API 早期和传统使用的风格。在调用异步函数时,需要提供一个函数作为参数 (即回调函数)。当异步任务完成后,系统会调用这个回调函数,并将结果作为参数传递给它。

bash 复制代码
// 回调风格示例
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    // 异步操作(查询标签页)完成后,这段代码才会被执行
    console.log("当前激活的标签页 ID 是:", tabs[0].id);
    // 这里如果发生错误,错误处理会很复杂(回调地狱)
});

console.log("这行代码会先于上面的结果被打印");

🟢Promise 风格(Promise Style)- 现代 Firefox/Edge 推荐风格

Promise 是一种更现代的异步处理方式,它代表了一个未来可能完成 的异步操作的结果。它能更好地处理异步操作的成功(then)和失败(catch ,并能通过链式调用(Promise Chain)解决回调函数嵌套过深的问题(回调地狱)。

chrome也正在转向这种风格。

bash 复制代码
// Promise 风格示例
browser.tabs.query({active: true, currentWindow: true})
    .then(tabs => {
        // 异步操作(查询标签页)成功后,这段代码才会被执行
        console.log("当前激活的标签页 ID 是:", tabs[0].id);
    })
    .catch(error => {
        // 捕获异步操作中的错误
        console.error("查询标签页时出错:", error);
    });

console.log("这行代码会先于上面的结果被打印");

4.2 使用 WebExtension Polyfill 来统一

WebExtension Polyfill 是一个小的 JavaScript 库,它会自动检测当前运行的环境(Chrome、Edge 还是 Firefox),然后:

  • 如果发现浏览器使用 browser 命名空间(Firefox 的标准),它会将所有 browser.* 方法映射到 chrome.* 方法。
  • 如果发现浏览器使用 chrome 命名空间(Chrome/Edge 的标准),它会反过来创建缺失的 browser 对象,并将其所有方法映射到 chrome.*。

文件地址:https://github.com/mozilla/webextension-polyfill

本文写的示例很简单,只需要稍改一下,不使用Polyfill ,就能兼容三大浏览器:

json 复制代码
{
  "manifest_version": 3,
  "name": "简单的Hello World插件",
  "version": "1.0",
  "description": "一个用于演示浏览器插件基本功能的简单示例。",
  "action": {
    "default_title": "点击我!",
    "default_popup": "popup.html"
  },
  "permissions": [
    "activeTab",
    "scripting"
  ],
  "browser_specific_settings": {
    "gecko": {
      "id": "helloworld@example.com",
      "strict_min_version": "109.0"
    }
  }
}

Gecko 是 Firefox 浏览器的核心引擎名称,在 Manifest V3 标准下,Chrome 是在安装时自动生成 ID 的,但 Firefox 强制要求开发者在 manifest.json 里显式声明这个 ID。如果不写,Firefox 在加载插件时会直接报错,认为这是一个无效的插件。

bash 复制代码
"browser_specific_settings": {        // 1. 浏览器专用设置
    "gecko": {                        // 2. 指定针对 Gecko 内核(即 Firefox)
      "id": "helloworld@example.com", // 3. 插件的唯一 ID(必须)
      "strict_min_version": "109.0"   // 4. 最低支持的 Firefox 版本
    }
  }

edge和chrome是类似的,打开开发人员选项即可加载。

chrome是在扩展界面,点击设置:调试附加组件,选择:manifest.json即可。

五、发布浏览器扩展

  1. 源码分享 / 本地安装

    • 直接分享扩展目录(解压后的文件夹)或打包成 .crx 文件都可以本地安装。
    • 注意:Chrome 和 Edge 对直接拖入目录的本地安装有安全限制,本地安装一般在开发者模式下进行。
    • 安装 .crx 后,可以删除 .crx 文件,因为浏览器已经加载了扩展;本地目录方式安装,则源文件不可删除。
  2. 发布到浏览器扩展商店

    • 需要注册开发者账号(Chrome Web Store 是一次性 5 美元费用,火狐免费),提交扩展并通过审核才能上架。
    • 扩展需符合规范:icon、描述、权限声明、文档等。
    • 上架后用户可直接下载安装,无需手动文件操作。
      注册地址:https://chrome.google.com/webstore/devconsole/register
相关推荐
qq_296544651 小时前
安卓版Google(谷歌地球),安卓谷歌(Google)地图,谷歌翻译,谷歌(Chrome)浏览器,手机版Edge,浏览器等安卓版浏览器下载
前端·chrome
今天也想MK代码1 小时前
JS 注入机制深度解析
java·前端·javascript
一字白首1 小时前
Vue 进阶,指令补充 + computed+watch
前端·javascript·vue.js
暮之沧蓝1 小时前
React(18-19)总结
前端·react.js·前端框架
HIT_Weston1 小时前
50、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(二)
前端·ubuntu·gitlab
我太想进步了C~~1 小时前
Prompt Design(提示词工程)入门级了解
前端·人工智能·算法
crary,记忆1 小时前
如何理解 React的UI渲染
前端·react.js·ui·前端框架
苏打水com1 小时前
Day1-3 夯实基础:HTML 语义化 + CSS 布局实战(对标职场 “页面结构搭建” 核心需求)
前端·css·html·js
m0_740043731 小时前
mapState —— Vuex 语法糖
java·前端·javascript·vue.js