Chrome 扩展 开发技术文档与操作流程
基于你提供的 manifest.json(Manifest V3),本文件说明各字段含义、建议的工程结构、示例代码片段、开发/调试流程以及常见注意事项,方便你快速开发和测试扩展。
1 概览(来自Demo manifest.json)
关键字段说明:
- manifest_version: 3 — 使用 Manifest V3(服务工作线程 background service worker)。
- name / version / description — 扩展元信息。
- permissions:
- sidePanel: 使用侧边栏 API(在支持的 Chrome 版本可用)。
- activeTab: 允许在用户与扩展交互后对当前标签执行短期权限操作。
- webRequest: 监听网络请求(注意:MV3 中有部分限制,不能拦截/修改除非声明 webRequestBlocking,且推荐使用 declarativeNetRequest)。
- webNavigation: 监听导航事件。
- storage: 使用 chrome.storage。
- tabs: 访问/控制标签页信息。
- host_permissions: 针对特定域名的主机权限(test.xxxxxx.me 与 localhost:3000)。
- action.default_icon: 浏览器工具栏图标。
- background.service_worker: background.js(作为服务工作线程)。
- content_scripts: content.js 注入所有页面(run_at=document_end)。
- side_panel.default_path: popup.html 将作为侧边栏内容页面(在支持侧边栏的 Chrome 版本中可见)。
- icons: 扩展图标。
2 推荐工程结构
建议在项目目录下创建如下文件/目录:
- manifest.json(你已提供)
- background.js // 服务工作线程
- content.js // 注入脚本
- popup.html // 侧边栏 / 可复用作为 popup
- popup.css, popup.js // 侧边栏页面样式与逻辑(可选)
- icons/
- icon.png (16/48/128)
- README.md // 说明文档
- assets/ // 其他资源
3 示例代码(最小可运行模板)
示例 background.js:
// background.js (service worker)
chrome.runtime.onInstalled.addListener(() => {
console.log('扩展已安装(service worker)');
});
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log('来自内容脚本或页面的消息:', message, '来自:', sender);
if (message.type === 'PING') {
sendResponse({type: 'PONG', ts: Date.now()});
}
// 返回 true 如果要异步 sendResponse
return true;
});
// 示例:监听 webNavigation(需要 permissions:webNavigation)
chrome.webNavigation.onCompleted.addListener((details) => {
console.log('导航完成:', details);
}, {url: [{hostContains: ''}]});
示例 content.js:
// content.js
console.log('content.js 已注入到页面:', location.href);
// 向 background 发消息并接收响应
chrome.runtime.sendMessage({type: 'PING', page: location.href}, (response) => {
console.log('来自 background 的响应:', response);
});
// 例如把页面标题发送给 background
chrome.runtime.sendMessage({type: 'PAGE_INFO', title: document.title});
示例 popup.html(也可作为侧边栏页面):
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>扩展侧边栏</title>
<style>
body { font-family: Arial, sans-serif; margin: 12px; }
button { padding: 6px 10px; }
</style>
</head>
<body>
<h3>侧边栏 / 弹窗</h3>
<div id="status">等待操作</div>
<button id="getTab">获取当前标签信息</button>
<script>
document.getElementById('getTab').addEventListener('click', async () => {
// 使用 tabs 权限
const tabs = await chrome.tabs.query({active: true, currentWindow: true});
const tab = tabs[0];
document.getElementById('status').textContent = tab ? tab.title + ' - ' + tab.url : '未找到标签';
// 向 content 脚本发送消息
chrome.tabs.sendMessage(tab.id, {type: 'FROM_PANEL', text: 'Hello from side panel'}, (resp) => {
console.log('content 返回:', resp);
});
});
</script>
</body>
</html>
4 开发与调试操作流程(逐步)
-
准备环境
- Chrome(推荐最新稳定版或 Canary,用于测试新 API 如 sidePanel)。
- 一个包含 manifest.json 和上述文件的文件夹。
-
本地文件准备
- 保存 manifest.json(已提供)。
- 新建 background.js、content.js、popup.html、icon.png 等文件(可先用示例模板)。
-
在浏览器中加载未打包扩展
- 打开 chrome://extensions。
- 开启右上角的“开发者模式”。
- 点击“加载已解压的扩展程序” -> 选择项目目录。
- 加载后会在扩展列表中看到你的扩展。
-
调试 Service Worker(background)
- 在 chrome://extensions 找到你的扩展,点击“服务工作线程 (background) 的 Inspect(检查)”进入控制台。
- 如果服务工作线程未在运行,可点击扩展页面上的“刷新”按钮以触发 onInstalled 或手动调用 chrome.runtime.reload() 来重启。
-
调试 Content Script
- 打开任意页面(content_scripts.matches 设置为 "<all_urls>",因此会注入 content.js)。
- 打开该页面的 DevTools(F12),查看 Console 中 content.js 的输出日志(如 console.log)。
-
调试侧边栏(side_panel)
- 在支持侧边栏的 Chrome 版本中,点击侧边栏按钮或工具栏中的扩展入口以打开侧边栏,侧边栏会载入 popup.html。
- 也可通过 chrome.sidePanel API 在 background 中设置/打开侧边栏(需注意不同 Chrome 版本的 API 差异)。
-
测试权限相关功能
- 测试 chrome.storage:在 popup 或 background 中读写 chrome.storage.local。
- 测试 webRequest/webNavigation:在 background 中添加监听并打开匹配 host 的页面查看日志(注意 webRequest 的范围与限制)。
- 测试 tabs 与 scripting(MV3 中推荐 chrome.scripting.executeScript 来注入代码)。
-
迭代
- 修改文件后在 chrome://extensions 点击“刷新”扩展(或使用自动化脚本重载)。
- 每次修改 background.js 时,service worker 需要重新加载:点击扩展页的“Service worker”下的 Reload 按钮或刷新扩展。
5 消息传递与常见 API 使用(要点)
-
content -> background chrome.runtime.sendMessage({...}, callback); background:chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {...});
-
background -> content chrome.tabs.sendMessage(tabId, {...}, callback);
-
MV3 注入脚本(替代 tabs.executeScript) chrome.scripting.executeScript({target: {tabId}, files: ['content.js']});
-
存储 chrome.storage.local.set({key: value}, () => {}); chrome.storage.local.get(['key'], (res) => {});
-
webRequest 注意事项
- 在 MV3 中,webRequest 在某些平台/用例下有能力限制(尤其是拦截/阻断请求需要 webRequestBlocking 权限;建议改用 declarativeNetRequest)。
- webRequest 仅在匹配 host_permissions 的域名下有数据。
-
sidePanel
- side_panel.default_path 会让你的扩展在支持的 Chrome 中显示侧边栏页面。
- 不同 Chrome 版本对 sidePanel API 支持不同,使用时请在目标浏览器上验证。
6 常见问题与排查建议
-
content.js 没有注入:
- 检查 manifest 中 content_scripts.matches 是否覆盖当前页面(<all_urls> 会注入所有页面,除 chrome:// 等受限页面)。
- 检查 run_at 是否合适(document_end、document_idle 等)。
- 检查是否被 CSP 阻止(某些页面可能阻止脚本注入)。
-
background service worker 无日志:
- 在 chrome://extensions 中打开 Service worker 的 Inspect(检查)面板。
- 注意 service worker 是临时的;只有在事件触发时才会记录或运行。可以把重要的 debug 日志放在事件处理里或在控制台手动 reload。
-
webRequest 未触发:
- 确认 host_permissions 包含目标域名。
- webRequest 事件不会触发受浏览器策略保护的内部请求(如 chrome://)。
-
权限过多或报隐私问题:
- 遵循最小权限原则,只申请必要权限。
- 在发布时在商店说明用途及隐私声明。
7 安全与隐私建议
- 最小权限原则:尽量把 host_permissions 限制到确切域名或子路径,避免使用 "<all_urls>"(除非必要)。
- 在向用户请求权限时,清晰地说明为什么需要这些权限。
- 如果处理用户数据(个人信息、cookies、页面内容等),在隐私政策中明确说明存储和使用方式。
- 避免在 content script 中暴露敏感信息到页面全局作用域(使用闭包或模块化)。
8 发布检查清单
- 测试所有已声明权限的功能在目标 Chrome 版本上正常工作。
- 完成扩展图标(16/48/128)。
- 填写 Chrome Web Store 必要的描述、截图、隐私政策链接。
- 最小化权限并移除未使用的权限(例如改用 declarativeNetRequest 替代 webRequest,若合适)。
- 测试在不同操作系统/浏览器渠道(Stable/Canary)上的侧边栏与 service worker 行为。
- 使用扩展打包工具生成 crx 或通过开发者面板上传 ZIP 并发布。
9 附录:对你的 manifest 的改进建议(可选)
- 如果需要拦截/阻断网络请求,考虑增加 "webRequestBlocking" 权限或迁移到 declarativeNetRequest。
- 如果 content_scripts 不需要注入所有页面,建议改为更具体的 matches 列表以减少隐私暴露。
- 如果侧边栏仅在特定页面使用,可考虑动态创建侧边栏页面或根据 host 权限控制行为。
如果你愿意,我可以:
- 根据你的项目生成示例文件(background.js / content.js / popup.html)并把每个文件内容打包在一个压缩包里或直接列出文件内容供你复制;
- 或者帮你把 manifest 中的权限最小化并提供修改建议(例如限定 host 范围或替换 webRequest 为 declarativeNetRequest)。
你想先要哪项帮助?例如:生成完整示例文件(可直接加载调试)还是优化 manifest 权限?谢谢!