Chrome插件开发实战,教你从零打造高效Chrome扩展
目录
5. popup.html 与 popup.js (用户交互界面)
6. background.js (后台服务与 API 调用)

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。
Chrome 插件开发,本质上是利用 Web 技术(HTML, CSS, JavaScript) 在浏览器环境中运行的一套小程序。它能让你定制浏览器行为、扩展网页功能、与外部 API 交互。
本指南将带你从零开始,创建一个具备前端工程化实践的 Chrome 插件,并深度调用 API。
一、 项目准备:你的第一个 Chrome 插件
1. 插件基础结构
一个最简单的 Chrome 插件包含以下核心文件:
manifest.json:插件的“身份证”,描述插件名称、版本、权限、脚本等。popup.html:插件图标点击后弹出的窗口(可选)。popup.js:控制popup.html行为的 JavaScript。content.js:注入到目标网页执行的 JavaScript。background.js:后台服务脚本,处理持久性任务、事件监听。
2. 创建项目目录
在你喜欢的目录下创建一个新文件夹,例如 my-chrome-extension。
3. manifest.json (核心配置)
创建 manifest.json 文件,这是插件的入口。
{
"manifest_version": 3, // 推荐使用 Manifest V3
"name": "My Awesome Extension",
"version": "1.0",
"description": "A simple example Chrome Extension.",
"permissions": [
"activeTab", // 允许访问当前激活标签页
"scripting", // 允许注入 content scripts
"storage", // 允许使用 chrome.storage API
"https://api.example.com/*" // 允许访问特定 API 域名 (必填!否则无法跨域请求)
],
"action": {
"default_popup": "popup.html", // 点击插件图标时显示的文件
"default_icon": {
"16": "images/icon16.png", // 16x16 像素图标
"48": "images/icon48.png", // 48x48 像素图标
"128": "images/icon128.png" // 128x128 像素图标
}
},
"background": {
"service_worker": "background.js" // 后台服务脚本 (Manifest V3 使用 Service Worker)
},
"icons": {
"16": "images/icon16.png",
"48": "images/icon48.png",
"128": "images/icon128.png"
}
}
4. 制作图标
在项目根目录下创建 images 文件夹,并放置 icon16.png, icon48.png, icon128.png。你可以用任何图片编辑工具生成。
5. popup.html 与 popup.js (用户交互界面)
创建 popup.html:
<!DOCTYPE html>
<html>
<head>
<title>My Extension</title>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<h1>Hello from My Extension!</h1>
<button id="fetchDataBtn">Fetch Data from API</button>
<div id="dataDisplay"></div>
<script src="popup.js"></script>
</body>
</html>
创建 popup.js:
document.addEventListener('DOMContentLoaded', function() {
const fetchDataBtn = document.getElementById('fetchDataBtn');
const dataDisplay = document.getElementById('dataDisplay');
fetchDataBtn.addEventListener('click', async () => {
dataDisplay.innerText = 'Loading...';
try {
// 调用 background.js 中的方法来获取数据,直接在 popup.js 中调用 chrome.runtime.sendMessage()
// 涉及到跨域API请求,最好在 background.js 中处理,避免 CSP (Content Security Policy) 问题
const response = await chrome.runtime.sendMessage({ action: "fetchApiData" });
if (response.success) {
dataDisplay.innerText = JSON.stringify(response.data, null, 2);
} else {
dataDisplay.innerText = `Error: ${response.error}`;
}
} catch (error) {
dataDisplay.innerText = `Error sending message: ${error}`;
}
});
});
6. background.js (后台服务与 API 调用)
创建 background.js:
// background.js
// 监听来自 popup.js 或 content.js 的消息
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.action === "fetchApiData") {
fetchDataFromApi().then(data => {
sendResponse({ success: true, data: data });
}).catch(error => {
sendResponse({ success: false, error: error.message });
});
return true; // 表示将异步发送响应
}
// 可以添加其他 action 的处理
}
);
async function fetchDataFromApi() {
const apiUrl = 'https://jsonplaceholder.typicode.com/todos/1'; // 示例 API
const response = await fetch(apiUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
// 如果 API 需要认证,在这里添加 Authorization header
// 'Authorization': 'Bearer YOUR_API_KEY'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
重要:manifest.json 中的 permissions 必须包含你请求的 API 域名,否则 fetch 会报 CORS 错误。
7. content.js (与网页内容交互 - 可选)
如果你想操作当前网页的内容,可以创建 content.js。
- 在
manifest.json中需要配置content_scripts:
// ... manifest.json ...
"content_scripts": [
{
"matches": ["<all_urls>"], // 作用于所有网页
"js": ["content.js"]
}
],
// ...
content.js 示例:
console.log("Content script injected!");
// 示例:修改网页标题
// document.title = "Modified by My Extension";
// 示例:通过 message passing 与 background.js 交互
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.action === "getPageTitle") {
sendResponse({ title: document.title });
}
}
);

二、 加载与调试插件
-
打开 Chrome 扩展程序页面:
- 在 Chrome 地址栏输入
chrome://extensions/并回车。
- 在 Chrome 地址栏输入
-
启用开发者模式:
- 在页面右上角,打开“开发者模式”开关。
-
加载已解压的扩展程序:
- 点击左上角的“加载已解压的扩展程序”按钮。
- 选择你创建的插件项目根目录(例如
my-chrome-extension)。 - 你的插件会出现在扩展程序列表中。
-
调试:
- Popup 调试:在插件图标上右键,选择“检查 popup”。会打开一个类似 DevTools 的界面,可以调试
popup.js。 - Background 调试:在
chrome://extensions/页面,找到你的插件,点击“Service worker”的链接。会打开一个 DevTools 界面,可以调试background.js。 - Content Script 调试:在目标网页中打开 DevTools,切换到 Console 或 Sources 标签页,可以看到
content.js的输出和进行调试。
- Popup 调试:在插件图标上右键,选择“检查 popup”。会打开一个类似 DevTools 的界面,可以调试
三、 前端工程化实践
当插件变得复杂,静态文件直接管理会混乱。
1. 使用打包工具 (Vite/Webpack)
安装:
cd my-chrome-extension
npm init -y
npm install vite --save-dev
npm install @vitejs/plugin-legacy --save-dev # 可选,用于兼容老版本浏览器
配置 vite.config.js:
import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';
export default defineConfig({
plugins: [
legacy({ // 兼容性配置
targets: ['defaults', 'not IE 11']
}),
// Vite 默认会生成 index.html,但 Chrome 插件是 manifest.json 作为入口
// 需要特殊处理,或者将 popup.html 作为 Vite 的入口
],
build: {
// 打包输出到插件根目录,并保持原有的 manifest.json
outDir: 'dist', // 打包输出目录
rollupOptions: {
input: { // 定义入口文件
popup: 'popup.html', // popup.js 会自动引入
// background: 'background.js' // background.js 作为 service worker 不需要在这里单独入口
},
output: {
assetFileNames: 'assets/[name].[hash][extname]', // 资源文件输出命名
entryFileNames: '[name].js' // 入口文件输出命名
}
},
emptyOutDir: true, // 清空输出目录
},
// 如果你的 manifest.json 引用了 .js 文件,直接放在根目录即可,Vite 会处理
// 如果 manifest.json 放在 dist 目录,需要调整 manifest.json 中的路径
// 最佳实践:manifest.json 保持在根目录,打包后手动复制到 dist
});
- 调整
manifest.json:- 将
popup.html指向打包后的文件(如dist/popup.html)。 background.js通常也不需要 Vite 处理,直接放在根目录。
- 将
- 运行构建:
npm run build
- 这会在
dist文件夹生成打包后的文件。 - 加载插件:在
chrome://extensions/页面,加载dist文件夹。
2. TypeScript 支持
- 安装:
npm install typescript --save-dev
npm install @types/chrome --save-dev # Chrome API 类型定义
- 创建
.ts文件:将popup.js,background.js,content.js重命名为.ts。 - 配置
tsconfig.json:
{
"compilerOptions": {
"target": "ES2020", // 现代 JS 目标
"module": "ESNext",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "dist", // TS 文件编译输出到 dist
"lib": ["ES2020", "DOM", "WebWorker"],
"types": ["chrome", "node"] // 包含 chrome 类型
},
"include": ["src/**/*"], // TS 源文件目录
"exclude": ["node_modules", "dist"] // 排除目录
}
- 修改 Vite 配置:
- 安装
@vitejs/plugin-vue或@vitejs/plugin-react(如果你使用 Vue/React)。 - 调整
vite.config.js,指向src目录作为入口。
- 安装

四、 API 深度调用与安全
- 跨域请求(CORS):
manifest.json的permissions中必须声明允许访问的 API 域名。"https://api.example.com/*"这种声明是强制的。- 如果你要访问
chrome://内的 API,是不允许的。
- 用户数据敏感性:
- 如果 API 调用涉及到用户敏感信息(如用户 ID、个人配置),切勿直接在
content.js中进行。 - 最佳实践:所有敏感 API 调用都应放在
background.js中。content.js负责收集网页信息,通过chrome.runtime.sendMessage发送给background.js,由background.js处理 API 请求,然后将结果sendResponse回去。
- 如果 API 调用涉及到用户敏感信息(如用户 ID、个人配置),切勿直接在
- API 密钥管理:
- 绝不硬编码:将 API Key 硬编码在插件的 JavaScript 文件中是极其危险的,用户可以轻易地在插件源码中看到。
- 推荐策略:
- 用户设置页面:为插件创建一个
options.html(在manifest.json中配置options_page)。让用户在插件的设置页面输入 API Key,然后通过chrome.storage.sync或chrome.storage.local保存。 - 背景脚本获取:
background.js在需要时从chrome.storage读取 API Key。
- 用户设置页面:为插件创建一个
- 错误处理与用户反馈:
- API 请求失败时,要给用户清晰的反馈(例如在 popup 中显示错误信息)。
- 使用
try...catch块处理fetch错误,并向用户说明原因。
五、 常见插件类型与进阶
- 数据抓取类:
content.js负责从网页 DOM 中提取数据,background.js负责将数据发送到后端 API。 - 网页增强类:
content.js动态修改页面样式或内容,background.js负责监听某些事件(如标签页切换、书签更新)。 - 快速访问类:
popup.html提供快捷链接、搜索框,popup.js通过chrome.tabs.create或chrome.runtime.sendMessage与后台交互。
六、总结
Chrome 插件开发是一个融合了前端工程化与浏览器 API 调用的过程。
- Manifest V3 是趋势,学习它的生命周期和权限管理。
- API 调用放在 background.js,并优先使用
chrome.storage管理敏感信息。 - 拥抱前端工程化工具(Vite/TypeScript),让你的插件开发更高效、更健壮。
- 永远要考虑用户体验和安全,尤其是 API Key 的管理。
通过以上步骤,你已经构建了一个具备基本 API 调用能力、支持前端工程化的 Chrome 插件。从这里开始,你可以探索更多浏览器 API,实现更丰富的功能!
如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。
更多推荐
所有评论(0)