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

手把手教你开发第一个 Chrome 扩展程序:网页字数统计插件

手把手教你开发第一个Chrome扩展程序:网页字数统计插件

前言

Chrome扩展程序(Chrome Extension)是基于Web技术(HTML、CSS、JavaScript)开发的浏览器增强工具,可实现自定义浏览体验、数据采集、功能增强等需求。本文将以网页字数统计插件为例,带你从0到1完成Chrome扩展开发,涵盖环境准备、核心功能实现、调试与发布全流程,采用最新的Manifest V3标准(2025年Chrome官方推荐版本),确保兼容性和安全性。

通过本教程,你将掌握:

  • Chrome扩展的核心组成结构
  • Manifest V3配置文件编写
  • 内容脚本(Content Script)与页面交互
  • 弹出页面(Popup)开发与数据展示
  • 扩展调试与Chrome网上应用店发布流程

一、开发环境准备

1.1 基础工具

  • 浏览器:Google Chrome 90+(Manifest V3最低要求版本)
  • 代码编辑器:Visual Studio Code(推荐安装插件:Chrome Extension Manifest Helper、ESLint)
  • 辅助工具:Chrome开发者工具(F12)、图标生成工具(如Iconifier)

1.2 项目结构创建

  1. 在电脑中新建文件夹,命名为WordCountExtension(扩展项目根目录)
  2. 在根目录下创建以下文件/文件夹结构:
WordCountExtension/
├─ icons/                # 扩展图标文件夹
│  ├─ 16.png             # 16x16像素图标(地址栏显示)
│  ├─ 48.png             # 48x48像素图标(扩展管理页显示)
│  └─ 128.png            # 128x128像素图标(应用商店显示)
├─ manifest.json         # 扩展配置文件(核心)
├─ popup.html            # 点击扩展图标弹出的页面
├─ popup.js              # 弹出页面的逻辑脚本
└─ content.js            # 注入网页的内容脚本(统计字数用)

提示:图标尺寸必须严格匹配,可使用在线图标生成工具将一张图片生成多尺寸版本,避免显示异常。

二、核心文件开发

2.1 配置文件:manifest.json(关键)

manifest.json是Chrome扩展的"身份证",定义了扩展的名称、权限、组件结构等核心信息,Manifest V3相比V2有重大变更(如用Service Worker替代Background Page),需严格按最新规范编写:

{"manifest_version": 3,          // 必须为3(V2将于2025年底停止支持)"name": "网页字数统计工具",       // 扩展名称(显示在扩展栏和应用商店)"version": "1.0.0",             // 版本号(更新时需递增,格式:主.次.修订)"description": "一键统计当前网页的文字数量,支持排除HTML标签和空白字符", // 描述(132字符内)"permissions": ["storage"],     // 所需权限(storage用于保存用户设置)"host_permissions": ["<all_urls>"], // 允许注入的网页范围(<all_urls>表示所有网页)"action": {                     // 扩展图标相关配置"default_popup": "popup.html",// 点击图标弹出的页面"default_icon": {             // 不同尺寸的图标"16": "icons/16.png","48": "icons/48.png","128": "icons/128.png"},"default_title": "统计当前网页字数" // 鼠标悬停图标时的提示文字},"content_scripts": [            // 注入网页的内容脚本{"matches": ["<all_urls>"],  // 匹配的网页URL(与host_permissions对应)"js": ["content.js"],       // 注入的JS文件"run_at": "document_end"    // 注入时机(网页DOM加载完成后)}],"icons": {                      // 扩展管理页显示的图标"16": "icons/16.png","48": "icons/48.png","128": "icons/128.png"}
}

关键说明:

  • manifest_version:3:必须指定为3,否则Chrome会拒绝加载
  • host_permissions:Manifest V3中单独列出网页访问权限,需明确声明
  • content_scripts:定义何时、向哪些网页注入脚本,run_at:document_end避免操作未加载的DOM

2.2 内容脚本:content.js(统计网页字数)

content.js会被注入到匹配的网页中,负责提取网页文本、统计字数,并与弹出页面通信。核心功能:

  1. 提取网页正文(排除HTML标签)
  2. 统计总字数、纯文字数(排除空白字符)
  3. 接收弹出页面的统计请求并返回结果
// content.js:注入网页的内容脚本// 1. 核心函数:统计网页字数
function countWords() {// 提取<body>内所有文本(排除HTML标签)const bodyText = document.body.innerText || '';// 统计总字符数(含空白字符)const totalChars = bodyText.length;// 统计纯文字数(排除空白字符:空格、换行、制表符)const pureText = bodyText.replace(/\s+/g, ''); // 正则替换所有空白字符const pureChars = pureText.length;// 统计单词数(以空格分隔,适用于英文网页)const words = bodyText.trim().split(/\s+/).filter(word => word.length > 0);const wordCount = words.length;return {totalChars,    // 总字符数pureChars,     // 纯文字数(无空白)wordCount,     // 单词数url: window.location.href, // 当前网页URLtitle: document.title     // 当前网页标题};
}// 2. 监听来自弹出页面的消息(接收统计请求)
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {// 判断请求类型if (request.action === 'countWords') {// 执行统计并返回结果const result = countWords();sendResponse(result); // 向popup.js发送统计结果}
});

技术细节:

  • document.body.innerText:提取网页可见文本,自动排除HTML标签
  • 正则表达式/\s+/g:匹配所有空白字符(空格、换行、制表符),用于纯文字数统计
  • chrome.runtime.onMessage:Manifest V3中用于组件间通信的API,替代V2的chrome.extension.onMessage

2.3 弹出页面:popup.html(用户交互界面)

popup.html是用户点击扩展图标后看到的界面,需简洁直观,包含"统计"按钮和结果展示区域,采用Tailwind CSS简化样式开发(无需本地引入,通过CDN加载):

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>网页字数统计</title><!-- 引入Tailwind CSS(快速构建样式,无需写原生CSS) --><script src="https://cdn.tailwindcss.com"></script><!-- 设置页面宽度(Chrome弹出页默认宽度较窄,需手动指定) --><style>body { width: 320px; padding: 16px; }.result-item { margin: 8px 0; }.result-label { font-weight: 600; color: #374151; }.result-value { color: #111827; }</style>
</head>
<body><!-- 标题 --><h3 class="text-lg font-bold text-center text-gray-800 mb-6">网页字数统计</h3><!-- 统计按钮 --><button id="countBtn" class="w-full py-2 px-4 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors mb-6">开始统计当前网页</button><!-- 结果展示区域(默认隐藏) --><div id="resultContainer" class="hidden"><div class="result-item"><span class="result-label">网页标题:</span><span id="pageTitle" class="result-value truncate"></span></div><div class="result-item"><span class="result-label">总字符数:</span><span id="totalChars" class="result-value"></span></div><div class="result-item"><span class="result-label">纯文字数:</span><span id="pureChars" class="result-value"></span></div><div class="result-item"><span class="result-label">单词数(英文):</span><span id="wordCount" class="result-value"></span></div><!-- 保存结果按钮 --><button id="saveBtn" class="w-full mt-6 py-2 px-4 bg-green-500 text-white rounded-md hover:bg-green-600 transition-colors">保存结果到本地</button></div><!-- 引入弹出页面逻辑脚本(必须放在body末尾,确保DOM加载完成) --><script src="popup.js"></script>
</body>
</html>

设计说明:

  • 宽度设置为320px:Chrome弹出页过宽会自动出现滚动条,320px是兼顾内容和体验的最佳宽度
  • Tailwind CSS CDN:避免本地引入CSS文件,减少项目体积,适合简单界面
  • 结果区域默认隐藏:点击统计按钮后才显示,避免空界面影响用户体验

2.4 弹出页面脚本:popup.js(交互逻辑)

popup.js负责处理弹出页面的用户交互,包括:

  1. 点击"统计"按钮,向content.js发送统计请求
  2. 接收统计结果并更新界面
  3. 点击"保存"按钮,用Chrome Storage保存结果
// popup.js:弹出页面的逻辑脚本// 页面加载完成后执行
document.addEventListener('DOMContentLoaded', () => {// 获取DOM元素const countBtn = document.getElementById('countBtn');const saveBtn = document.getElementById('saveBtn');const resultContainer = document.getElementById('resultContainer');const pageTitleEl = document.getElementById('pageTitle');const totalCharsEl = document.getElementById('totalChars');const pureCharsEl = document.getElementById('pureChars');const wordCountEl = document.getElementById('wordCount');// 1. 统计按钮点击事件countBtn.addEventListener('click', async () => {try {// 禁用按钮,防止重复点击countBtn.disabled = true;countBtn.textContent = '统计中...';// 获取当前活跃的标签页(用户正在浏览的标签页)const [currentTab] = await chrome.tabs.query({ active: true, currentWindow: true });// 向content.js发送消息(请求统计字数)// 参数1:发送的消息对象,参数2:目标标签页IDconst result = await chrome.tabs.sendMessage(currentTab.id, { action: 'countWords' });// 更新界面显示统计结果resultContainer.classList.remove('hidden');pageTitleEl.textContent = result.title;totalCharsEl.textContent = result.totalChars;pureCharsEl.textContent = result.pureChars;wordCountEl.textContent = result.wordCount;// 保存结果到全局变量,供保存按钮使用window.countResult = result;} catch (error) {// 错误处理(如网页未加载content.js、统计失败)alert('统计失败:' + (error.message || '请刷新网页后重试'));} finally {// 恢复按钮状态countBtn.disabled = false;countBtn.textContent = '开始统计当前网页';}});// 2. 保存按钮点击事件(使用Chrome Storage API)saveBtn.addEventListener('click', async () => {if (!window.countResult) {alert('请先执行统计操作');return;}try {// 禁用按钮saveBtn.disabled = true;saveBtn.textContent = '保存中...';// 获取已保存的历史记录const { history = [] } = await chrome.storage.local.get('history');// 添加当前统计结果(包含时间戳)const newRecord = {...window.countResult,timestamp: new Date().toLocaleString() // 本地时间};history.unshift(newRecord); // 添加到数组开头(最新的在前面)// 限制历史记录数量(最多保存20条)if (history.length > 20) {history.pop(); // 删除最早的记录}// 保存到Chrome本地存储(storage.local:仅当前设备可见)await chrome.storage.local.set({ history });alert('保存成功!已保存到历史记录');} catch (error) {alert('保存失败:' + error.message);} finally {// 恢复按钮状态saveBtn.disabled = false;saveBtn.textContent = '保存结果到本地';}});
});

关键API说明:

  • chrome.tabs.query:获取当前活跃标签页信息,参数{active: true, currentWindow: true}表示当前窗口的活跃标签
  • chrome.tabs.sendMessage:向指定标签页的content.js发送消息,Manifest V3中必须使用async/await或回调处理结果
  • chrome.storage.local:本地存储API,需在manifest.json中声明"storage"权限,数据仅保存在当前设备,无大小限制(相比localStorage更适合扩展)

三、扩展加载与调试

3.1 加载未打包扩展到Chrome

开发过程中,需将本地项目加载到Chrome中测试,步骤如下:

  1. 打开Chrome浏览器,在地址栏输入chrome://extensions/进入扩展管理页
  2. 开启右上角的"开发者模式"(Developer mode)开关
  3. 点击"加载已解压的扩展程序"(Load unpacked)按钮
  4. 在弹出的文件选择框中,选择项目根目录WordCountExtension
  5. 加载成功后,扩展栏会显示你的插件图标(若未显示,点击扩展栏的"拼图"图标,找到插件并固定)

常见问题:

  • 加载失败提示"Manifest文件无效":检查manifest.json是否有语法错误(如逗号遗漏、引号不匹配),Manifest V3不支持注释,需删除所有//注释
  • 图标不显示:检查icons文件夹路径是否正确,图标尺寸是否符合要求
  • content.js未注入:检查manifest.jsoncontent_scripts.matches是否包含当前网页URL(如"<all_urls>"表示所有网页)

3.2 调试技巧(关键)

Chrome提供强大的调试工具,帮助定位扩展中的bug,针对不同组件有不同的调试方式:

3.2.1 调试弹出页面(popup.html/popup.js)
  1. 点击扩展图标打开弹出页面
  2. 右键点击弹出页面空白处,选择"检查"(Inspect),打开开发者工具
  3. 在"Elements"面板查看DOM结构,"Console"面板查看日志,"Sources"面板调试popup.js代码

提示:弹出页面关闭后,调试工具也会关闭,如需保持调试状态,可在弹出页面中按F12打开工具后,勾选"Keep"选项(在工具右上角)。

3.2.2 调试内容脚本(content.js)
  1. 打开任意网页(如百度首页)
  2. F12打开网页的开发者工具
  3. 切换到"Sources"面板,在左侧导航栏找到"Content scripts" → 你的扩展名称 → content.js
  4. 在代码行号处点击设置断点,刷新网页后即可调试

注意:默认情况下,Chrome开发者工具会忽略内容脚本,需在"Sources"面板的"Settings"(齿轮图标)中,取消勾选"Hide content scripts"。

3.2.3 查看扩展错误日志
  1. 进入扩展管理页(chrome://extensions/
  2. 开启"开发者模式"后,点击你的扩展下方的"查看视图"(Inspect views)
  3. 在打开的工具中,"Console"面板会显示扩展的所有错误日志(如权限问题、API调用错误)

四、功能测试与优化

4.1 核心功能测试

按以下步骤测试插件是否正常工作:

  1. 打开任意网页(如一篇博客文章)
  2. 点击扩展图标,打开弹出页面
  3. 点击"开始统计当前网页"按钮,查看是否显示正确的统计结果
  4. 点击"保存结果到本地"按钮,确认是否提示保存成功
  5. 打开扩展管理页,点击"查看视图" → "storage",检查是否保存了历史记录

4.2 常见问题优化

  1. 统计结果为0:检查网页是否加载了content.js,可在网页开发者工具的"Console"面板输入chrome.runtime.sendMessage({action:'countWords'}, console.log)测试是否返回结果
  2. 跨域问题:Manifest V3中host_permissions需明确声明,若统计特定网站失败,检查该网站是否在matches列表中
  3. 性能优化:对于超长网页(如小说网站),统计可能耗时,可在content.js中添加进度提示,或分块处理文本
  4. 用户体验:添加加载状态(如按钮禁用、加载动画),避免用户重复点击;结果区域添加滚动条,适配长标题

五、打包与发布到Chrome网上应用店

5.1 打包扩展程序

开发完成后,需将项目打包为ZIP文件,用于发布到应用商店:

  1. 进入Chrome扩展管理页(chrome://extensions/
  2. 点击"打包扩展程序"(Pack extension)按钮
  3. 在"扩展程序根目录"中选择项目根目录WordCountExtension,无需填写"私有密钥文件"(首次打包会自动生成)
  4. 点击"打包扩展程序",生成WordCountExtension.crx(打包后的扩展文件)和WordCountExtension.pem(私有密钥,用于后续更新)

重要提示:私有密钥文件(.pem)需妥善保存,丢失后无法更新已发布的扩展程序。

5.2 发布到Chrome网上应用店

  1. 创建开发者账号
    • 访问Chrome开发者控制台
    • 用Google账号登录,支付一次性注册费(20美元,2025年价格)
    • 完成账号验证(需提供手机号)
  1. 准备发布材料
    • 打包好的ZIP文件(注意:ZIP文件需包含manifest.json在根目录,不能有多余文件夹)
    • 扩展图标(128x128像素,无圆角,背景透明)
    • 应用商店展示图(至少1张,尺寸推荐1280x800像素)
    • 扩展描述(分短描述和长描述,需说明功能和使用方法,支持Markdown)
  1. 上传扩展
    • 在开发者控制台点击"新建项目",输入扩展名称
    • 点击"上传新扩展",选择打包好的ZIP文件
    • 检查manifest.json中的信息(名称、版本、权限),确认无误后提交
  1. 审核与发布
    • Chrome网上应用店审核周期通常为1-3个工作日
    • 审核通过后,扩展会在应用商店上线,用户可搜索下载
    • 审核失败:根据邮件提示修改(常见原因:权限过度申请、功能无法使用、描述与功能不符)

发布最佳实践:

  • 权限最小化:仅申请必要的权限(如本插件仅需storage<all_urls>),避免用户不信任
  • 描述清晰:在应用商店描述中说明扩展的使用场景和优势,附截图或GIF演示
  • 版本管理:每次更新需递增manifest.json中的version号,如从1.0.0到1.0.1

六、扩展功能扩展建议

本教程实现的字数统计插件是基础版本,你可以在此基础上扩展更多功能,提升实用性:

  1. 历史记录管理:在popup.html中添加历史记录标签页,展示所有保存的统计结果,支持删除和导出
  2. 自定义统计规则:添加设置页面,允许用户选择是否统计标点符号、是否排除特定标签(如<script><style>
  3. 自动统计:在manifest.json中添加background服务 worker,实现网页加载完成后自动统计,无需手动点击
  4. 多语言支持:添加_locales文件夹,支持中文、英文等多语言界面
  5. 数据同步:将chrome.storage.local改为chrome.storage.sync,实现多设备统计结果同步(需用户开启Chrome同步功能)

七、总结

通过本教程,你已掌握Chrome扩展开发的核心流程:从项目结构创建、Manifest V3配置、核心组件(Content Script、Popup)开发,到扩展加载调试、打包发布。Chrome扩展开发门槛低(基于Web技术),但功能强大,可根据实际需求灵活扩展。

关键知识点回顾:

  • Manifest V3是当前推荐版本,需注意权限声明、组件通信方式的变化
  • 内容脚本(Content Script)运行在网页上下文,负责与网页交互
  • 弹出页面(Popup)是用户交互界面,通过chrome.tabs.sendMessage与内容脚本通信
  • Chrome Storage API用于保存用户数据,需在manifest.json中声明权限

后续可深入学习Chrome扩展的高级功能,如后台服务 worker、上下文菜单、通知API等,开发更复杂的扩展程序。

http://www.xdnf.cn/news/19837.html

相关文章:

  • 从竞态到原子:pread/pwrite 如何重塑高效文件 I/O?
  • 如何使文件夹内的软件或者文件不受windows 安全中心的监视
  • Java8特性
  • 【HarmonyOS 6】仿AI唤起屏幕边缘流光特效
  • leetcode-每日一题-人员站位的方案数-C语言
  • Spring 循环依赖问题
  • 《LINUX系统编程》笔记p8
  • 大模型RAG项目实战:RAG技术原理及核心架构
  • SpringBoot 事务管理避坑指南
  • 机器学习:从技术原理到实践应用的深度解析
  • 机器人抓取中的力学相关概念解释
  • JVM中产生OOM(内存溢出)的8种典型情况及解决方案
  • 初识NOSQL
  • 方法决定效率
  • git: 取消文件跟踪
  • SRE团队是干嘛的
  • 关于IDE的相关知识之一【使用技巧】
  • Spring Security 如何使用@PreAuthorize注解
  • Nano Banana 新玩法超惊艳!附教程案例提示词!
  • AI 设计工具天花板
  • 【android bluetooth 协议分析 21】【ble 介绍 3】【ble acl Supervision Timeout 介绍】
  • 黑马头条面试重点业务
  • 构建下一代智能金融基础设施
  • SpringBoot--手写日期格式转换工具类
  • TiDB v8.5.3 单机集群部署指南
  • ASP.NET Core上传文件到minio
  • 【leetcode】236. 二叉树的最近公共祖先
  • 利用Base64传输二进制文件并执行的方法(适合没有ssh ftp等传输工具的嵌入式离线场景)
  • 研发文档版本混乱的根本原因是什么,怎么办
  • ELK 统一日志分析系统部署与实践指南(上)