当前位置: 首页 > news >正文

Chrome 插件开发实战:从入门到进阶

一、引言

1.1 Chrome 插件简介

Chrome 插件,即扩展程序,是为增强 Google Chrome 浏览器功能而设计的小型软件。它能为用户提供丰富功能,如广告拦截、密码管理、页面翻译等,极大提升浏览体验与工作效率。例如,AdBlock 可屏蔽网页广告,LastPass 能安全管理密码,Grammarly 可检查拼写语法错误。

Chrome 插件运行在浏览器沙盒环境,基于 HTML、CSS 和 JavaScript 等 Web 技术开发,开发者可借助浏览器 API 实现与浏览器及网页内容的交互。

1.2 开发 Chrome 插件的意义与价值

对于开发者,开发 Chrome 插件可拓展技术能力,将创意转化为实用工具,还能通过 Chrome Web Store 发布作品获取收益与用户反馈。对用户而言,插件能定制浏览体验,满足个性化需求,提高上网效率与乐趣。插件还能促进浏览器生态发展,推动更多创新应用出现。

1.3 本文目标与读者对象

本文旨在带领读者全面了解 Chrome 插件开发流程,从基础概念到实战开发,再到发布维护,助力读者掌握开发技能,开发出实用插件。适合有一定 Web 开发基础(熟悉 HTML、CSS、JavaScript),想学习 Chrome 插件开发的初学者,以及有相关经验但希望深入了解的开发者。

二、Chrome 插件开发基础

2.1 开发环境搭建

2.1.1 安装 Chrome 浏览器

确保安装最新版本的 Chrome 浏览器,可从 Chrome 官网(https://www.google.com/chrome/)下载。新版本通常支持更多功能与 API,利于开发。

2.1.2 启用开发者模式

打开 Chrome 浏览器,进入菜单 “更多工具”>“扩展程序”,打开右上角的 “开发者模式” 切换按钮。开启后可加载未打包的扩展程序,方便开发调试。

2.1.3 选择合适的文本编辑器

推荐使用 Visual Studio Code,它功能强大,有丰富插件支持,如 ESLint 可检查 JavaScript 代码规范,Live Server 可实时预览网页。也可选择 Sublime Text、Atom 等。

2.2 Chrome 插件的基本结构

2.2.1 manifest.json 文件详解

manifest.json 是插件核心配置文件,定义插件基本信息、权限、功能等。关键字段如下:

  • manifest_version:指定清单文件版本,当前常用 2 或 3,建议用 3 以获取新特性与安全改进。
  • name:插件名称,显示在 Chrome 插件管理页面和 Chrome 网上应用店。
  • version:插件版本号,采用语义化版本控制,如 “1.0”“1.1.1”。
  • description:插件简短描述,解释功能用途。
  • icons:定义不同尺寸图标,用于浏览器扩展程序页面和工具栏,如:

json

"icons": {"16": "icon16.png","48": "icon48.png","128": "icon128.png"
}

  • browser_action 或 page_action:定义浏览器操作按钮或页面操作按钮行为。browser_action 用于常用操作,点击后显示弹出窗口;page_action 用于特定页面操作,按钮在匹配页面才显示。如:

json

"browser_action": {"default_popup": "popup.html","default_icon": "icon.png"
}

  • permissions:插件所需 API 权限列表,如 “activeTab” 可访问当前活动标签页,“storage” 可进行数据存储。
  • background:指定后台脚本,MV3 中用 service_worker 字段指定,如:

json

"background": {"service_worker": "background.js"
}

  • content_scripts:定义内容脚本及其注入页面,如:

json

"content_scripts": [{"matches": ["<all_urls>"],"js": ["content.js"]}
]

表示 content.js 会注入到所有页面。

2.2.2 背景脚本(Background Scripts)

背景脚本在浏览器后台运行,处理长时间任务,如事件监听、消息传递、定时任务。MV3 中用 Service Worker 代替后台页面,提高性能与安全性。例如监听插件安装事件:

javascript

// background.js
chrome.runtime.onInstalled.addListener(() => {console.log('插件已安装');
});

还可监听标签页更新事件:

javascript

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {if (changeInfo.status === 'complete') {console.log('标签页', tabId, '已更新');}
});
2.2.3 内容脚本(Content Scripts)

内容脚本注入到网页,可直接访问修改网页 DOM。例如,修改网页背景颜色:

javascript

// content.js
document.body.style.backgroundColor = 'lightblue';

内容脚本与网页 DOM 交互,但不能直接访问浏览器 API,需通过消息传递与背景脚本通信。

2.2.4 弹出页面(Popup Pages)

弹出页面是插件用户界面,用户点击插件图标时显示。通常包含 HTML、CSS 和 JavaScript 文件。如 popup.html:

html

<!DOCTYPE html>
<html lang="zh - CN">
<head><meta charset="UTF - 8"><meta name="viewport" content="width=device - width, initial - scale = 1.0"><title>插件弹出页面</title><link rel="stylesheet" href="popup.css"><script src="popup.js"></script>
</head>
<body><h1>这是一个简单的弹出页面</h1><button id="click - me">点击我</button>
</body>
</html>

popup.js 处理按钮点击事件:

javascript

document.getElementById('click - me').addEventListener('click', () => {alert('按钮被点击了');
});

2.2.5 选项页面(Options Pages)

选项页面是插件设置页面,用户可自定义插件行为。创建选项页面需在 manifest.json 声明:

json

"options_page": "options.html"

options.html 示例:

html

<!DOCTYPE html>
<html lang="zh - CN">
<head><meta charset="UTF - 8"><meta name="viewport" content="width=device - width, initial - scale = 1.0"><title>插件选项页面</title><link rel="stylesheet" href="options.css"><script src="options.js"></script>
</head>
<body><h1>插件设置</h1><label for="color - setting">选择颜色:</label><input type="color" id="color - setting"><button id="save - settings">保存设置</button>
</body>
</html>

options.js 保存用户设置:

javascript

document.getElementById('save - settings').addEventListener('click', () => {const color = document.getElementById('color - setting').value;chrome.storage.sync.set({ colorSetting: color }, () => {console.log('设置已保存');});
});

2.3 Chrome 插件的生命周期与事件系统

2.3.1 插件生命周期

插件生命周期包括安装、更新、启动、运行、停止、卸载阶段。

  • 安装或更新:用户首次安装或插件有新版本时,浏览器加载初始化插件。可在 background 脚本监听 chrome.runtime.onInstalled 事件执行初始化操作,通过 reason 判断是安装还是更新:

javascript

chrome.runtime.onInstalled.addListener((details) => {if (details.reason === 'install') {console.log('插件首次安装');} else if (details.reason === 'update') {console.log('插件更新,旧版本:', details.previousVersion);}
});

  • 启动:用户打开浏览器,插件启动。可在此阶段初始化数据、设置默认状态。
  • 运行:插件启动后进入运行阶段,响应用户操作,监听处理浏览器事件,提供功能。
  • 停止:用户关闭浏览器,插件停止。可监听 chrome.runtime.onSuspend 事件保存数据、清理资源,但 Chrome 未提供浏览器关闭直接事件,可用 chrome.windows.onRemoved 事件在最后一个浏览器窗口关闭时执行操作:

javascript

let windowCount = 0;
chrome.windows.getAll((windows) => {windowCount = windows.length;
});
chrome.windows.onRemoved.addListener((windowId) => {windowCount--;if (windowCount === 0) {// 执行清理操作console.log('所有窗口已关闭,插件停止');}
});

  • 卸载:用户卸载插件,生命周期结束。可监听 chrome.runtime.onInstalled 事件的 uninstall 原因执行卸载操作:

javascript

chrome.runtime.onInstalled.addListener((details) => {if (details.reason === 'uninstall') {console.log('插件被卸载');}
});
2.3.2 事件系统

Chrome 插件事件系统让插件响应浏览器和用户事件。

  • 浏览器事件
    • 浏览器启动事件:监听 chrome.runtime.onStartup 事件,如:

javascript

chrome.runtime.onStartup.addListener(() => {console.log('浏览器启动');
});

  • 打开新窗口事件:监听 chrome.windows.onCreated 事件,如:

javascript

chrome.windows.onCreated.addListener((window) => {console.log('新窗口打开,窗口ID:', window.id);
});

  • 关闭窗口事件:监听 chrome.windows.onRemoved 事件,如:

javascript

chrome.windows.onRemoved.addListener((windowId) => {console.log('窗口关闭,窗口ID:', windowId);
});

  • 切换标签页事件:监听 chrome.tabs.onActivated 事件,如:

javascript

chrome.tabs.onActivated.addListener((activeInfo) => {console.log('标签页切换,新标签页ID:', activeInfo.tabId);
});

  • 网络事件
    • 请求发送事件:监听 chrome.webRequest.onBeforeRequest 事件,可拦截修改请求,如:

javascript

chrome.webRequest.onBeforeRequest.addListener((details) => {if (details.url.includes('example.com')) {return { redirectUrl: 'https://new - example.com' };}},{ urls: ['<all_urls>'] },['blocking']
);

  • 响应接收事件:监听 chrome.webRequest.onCompleted 事件,如:

javascript

chrome.webRequest.onCompleted.addListener((details) => {console.log('请求完成,URL:', details.url);},{ urls: ['<all_urls>'] }
);

  • 连接错误事件:监听 chrome.webRequest.onErrorOccurred 事件,如:

javascript

chrome.webRequest.onErrorOccurred.addListener((details) => {console.log('连接错误,URL:', details.url, ',错误信息:', details.error);},{ urls: ['<all_urls>'] }
);

  • 用户交互事件
    • 点击插件图标事件:监听 chrome.browserAction.onClicked 事件,如:

javascript

chrome.browserAction.onClicked.addListener((tab) => {console.log('插件图标被点击,当前标签页ID:', tab.id);
});

  • 选择插件菜单事件:先创建菜单,再监听 chrome.contextMenus.onClicked 事件,如:

javascript

chrome.contextMenus.create({id: "sampleContextMenu",title: "示例菜单",contexts: ["page"]
});
chrome.contextMenus.onClicked.addListener((info, tab) => {if (info.menuItemId === "sampleContextMenu") {console.log('示例菜单被选择');}
});

  • 使用快捷键事件:在 manifest.json 定义快捷键,监听 chrome.commands.onCommand 事件,如:

json

"commands": {"toggle - popup": {"suggested_key": {"default": "Ctrl+Shift+P","mac": "Command+Shift+P"},"description": "Toggle the popup"}
}

javascript

chrome.commands.onCommand.addListener((command) => {if (command === 'toggle - popup') {console.log('快捷键被使用,打开或关闭弹出窗口');}
});

三、实战案例:开发一个简单的 Chrome 插件

3.1 插件功能需求分析

我们开发一个 “页面信息展示” 插件,功能如下:

  • 点击插件图标,弹出窗口显示当前页面 URL、标题和加载时间。
  • 提供选项页面,用户可设置是否在弹出窗口显示页面描述(若有)。

3.2 创建项目结构

在项目目录创建以下文件结构:

plaintext

my - page - info - extension/
│
├── manifest.json
│
├── background.js
│
├── popup.html
│
├── popup.js
│
├── options.html
│
├── options.js
│
├── icons/
│   ├── icon16.png
│   ├── icon48.png
│   ├── icon128.png
│
└── styles/├── popup.css├── options.css

3.3 编写 manifest.json 文件

json

{"manifest_version": 3,"name": "页面信息展示插件","version": "1.0","description": "显示当前页面的URL、标题、加载时间等信息","icons": {"16": "icons/icon16.png","48": "icons/icon48.png","128": "icons/icon128.png"},"action": {"default_popup": "popup.html","default_icon": "icons/icon48.png"},"options_page": "options.html","background": {"service_worker": "background.js"},"permissions": ["activeTab","storage"]
}

3.4 开发背景脚本(background.js)

背景脚本监听页面加载完成事件,记录页面加载时间:

javascript

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {if (changeInfo.status === 'complete') {const startTime = performance.now();chrome.scripting.executeScript({target: { tabId: tabId },function: () => performance.now()}).then((results) => {const endTime = results[0].result;const loadTime = endTime - startTime;chrome.storage.local.set({ [tabId]: loadTime });});}
});

3.5 实现弹出页面(popup.html 和 popup.js)

popup.html 结构:

html

<!DOCTYPE html>
<html lang="zh - CN">
<head><meta charset="UTF - 8"><meta name="viewport" content="width=device - width, initial - scale = 1.0"><title>页面信息</title><link rel="stylesheet" href="styles/popup.css"><script src="popup.js"></script>
</head>
<body><h1>页面信息</h1><div id="url - info"><strong>URL:</strong><span id="page - url"></span></div><div id="title - info"><strong>标题:</strong><span id="page - title"></span></div><div id="load - time - info"><strong>加载时间:</strong><span id="page - load - time"></span>毫秒</div><div id="description - info"><strong>描述:</strong><span id="page - description"></span></div>
</body>
</html>

popup.js 获取并显示页面信息:

javascript

document.addEventListener('DOMContentLoaded', () => {chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {const tab = tabs[0];document.getElementById('page - url').textContent = tab.url;document.getElementById('page - title').textContent = tab.title;chrome.storage.local.get([tab.id], (data) => {document.getElementById('page - load - time').textContent = data[tab.id] || '未知';});chrome.scripting.executeScript({target: { tabId: tab.id },function: () => {const meta = document.querySelector('meta[name="description"]');return meta? meta.content : '';}}).then((results) => {document.getElementById('page - description').textContent = results[0].result;});});
});

3.6 设计选项页面(options.html 和 options.js)

options.html 结构:

html

<!DOCTYPE html>
<html lang="zh - CN">
<head><meta charset="UTF - 8"><meta name="viewport" content="width=device - width, initial - scale = 1.0"><title>插件选项</title><link rel="stylesheet" href="styles/options.css"><script src="options.js"></script>
</head>
<body><h1>插件选项</h1><input type

http://www.dtcms.com/a/343236.html

相关文章:

  • Python 面向对象编程入门:从思想到属性操作
  • PyTorch 环境配置
  • Telnet、ftp详解
  • 教育场景下禁用html5播放器拖动进度条的例子
  • python 项目编号 2025821 有关于中英文数据的收集、处理
  • mac的m3芯片通过Homebrew安装git
  • ES_分词
  • 2025-08-21 Python进阶9——__main__与lambda
  • Harbor私有仓库实战配置
  • FLUX-Text模型完全配置指南:从环境搭建到故障排除
  • 用例完备性1:用例模板
  • 数据结构-HashMap
  • Kubernetes“城市规划”指南:告别资源拥堵与预算超支,打造高效云原生都市
  • Typora 快速使用入门:15分钟掌握高效写作
  • 锅炉铸造件三维扫描尺寸及形位公差检测技术方案-中科米堆CASAIM
  • ⸢ 啟 ⸥ ⤳ 为什么要开这个专栏?
  • Ubuntu Server 系统安装 Docker
  • uni-app:实现文本框的自动换行
  • SpringBoot + Vue实现批量导入导出功能的标准方案
  • k8sday13数据存储(1.5/2)
  • 基于Matlab多技术融合的红外图像增强方法研究
  • C++---滑动窗口平滑数据
  • 瑞派亚宠展专访 | 以数智化重塑就医体验,共筑宠物健康新生态
  • 区块链存证操作
  • echarts关系图(Vue3)节点背景图连线设置
  • 2025.7.19卡码刷题-回溯算法-组合
  • IOS购买订阅通知信息解析说明Java
  • 设计模式3-模板方法模式
  • 爬虫基础学习-项目实践:每次请求,跟换不同的user-agent
  • 茶饮业内卷破局,从人力管理入手