You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
2 weeks ago | |
|---|---|---|
| .. | ||
| setCookie | 2 weeks ago | |
| README.md | 2 weeks ago | |
README.md
谷歌浏览器插件开发详细教程
目录
1. 插件概述
1.1 什么是Chrome扩展程序
Chrome扩展程序是基于Web技术(HTML、CSS、JavaScript)构建的小程序,用于增强Chrome浏览器的功能。
1.2 扩展程序类型
- 浏览器操作扩展:在工具栏添加图标
- 页面操作扩展:针对特定页面生效
- 内容脚本扩展:修改网页内容
- 开发工具扩展:扩展开发者工具
- 主题扩展:改变浏览器外观
1.3 扩展程序限制
- 无法访问浏览器核心功能
- 遵循同源策略
- 需要明确的权限声明
2. 开发环境配置
2.1 必要工具
- Chrome浏览器:72+版本
- 代码编辑器:VS Code、Sublime等
- 基础前端知识:HTML、CSS、JavaScript
2.2 开发模式开启
- 打开Chrome浏览器
- 访问
chrome://extensions/ - 开启右上角"开发者模式"
3. 插件基本结构
3.1 最小化结构
my-extension/
├── manifest.json # 配置文件
├── icon.png # 扩展图标
├── popup.html # 弹出页面
└── popup.js # 弹出页面脚本
3.2 manifest.json 详解
{
"manifest_version": 3,
"name": "我的扩展程序",
"version": "1.0.0",
"description": "扩展程序描述",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"action": {
"default_popup": "popup.html",
"default_title": "点击查看详情",
"default_icon": {
"16": "icons/icon16.png",
"32": "icons/icon32.png"
}
},
"permissions": [
"activeTab",
"storage",
"scripting"
],
"host_permissions": [
"https://*.example.com/*"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["https://*.example.com/*"],
"js": ["content.js"],
"css": ["content.css"]
}
],
"web_accessible_resources": [{
"resources": ["injected.js"],
"matches": ["<all_urls>"]
}]
}
4. 核心组件详解
4.1 后台脚本 (Background Script)
Manifest V3 使用 Service Worker
// background.js
chrome.runtime.onInstalled.addListener(() => {
console.log('扩展已安装');
});
// 监听消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'getData') {
sendResponse({ data: '处理后的数据' });
}
return true; // 保持消息通道开放
});
// 监听浏览器标签页更新
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete') {
// 页面加载完成
}
});
4.2 内容脚本 (Content Script)
// content.js
// 直接注入到网页上下文中
// 修改页面内容
document.body.style.backgroundColor = '#f0f0f0';
// 监听来自popup或background的消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === 'extractText') {
const text = document.body.innerText;
sendResponse({ text: text.substring(0, 100) });
}
});
// 向页面注入自定义脚本
const script = document.createElement('script');
script.src = chrome.runtime.getURL('injected.js');
document.head.appendChild(script);
4.3 弹出页面 (Popup)
<!-- popup.html -->
<!DOCTYPE html>
<html>
<head>
<style>
body {
width: 300px;
padding: 15px;
font-family: Arial, sans-serif;
}
button {
padding: 8px 16px;
background: #4285f4;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
</head>
<body>
<h3>我的扩展</h3>
<button id="actionBtn">执行操作</button>
<div id="result"></div>
<script src="popup.js"></script>
</body>
</html>
// popup.js
document.getElementById('actionBtn').addEventListener('click', async () => {
// 获取当前标签页
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
// 发送消息给内容脚本
const response = await chrome.tabs.sendMessage(tab.id, {
action: 'getPageInfo'
});
document.getElementById('result').textContent =
`页面标题: ${response.title}`;
});
// 使用存储API
chrome.storage.local.set({ key: 'value' }, () => {
console.log('数据已保存');
});
chrome.storage.local.get(['key'], (result) => {
console.log('读取的数据:', result.key);
});
5. 常用API
5.1 消息传递
// 发送消息
chrome.runtime.sendMessage(
{ action: 'doSomething', data: 'some data' },
response => console.log('响应:', response)
);
// 标签页内通信
chrome.tabs.sendMessage(tabId, message, callback);
5.2 存储API
// 本地存储
chrome.storage.local.set({ key: 'value' });
chrome.storage.local.get(['key'], result => {});
// 同步存储(跨设备同步)
chrome.storage.sync.set({ settings: { theme: 'dark' } });
// 监听存储变化
chrome.storage.onChanged.addListener((changes, area) => {
for (let key in changes) {
console.log(`${key} 从 ${changes[key].oldValue} 变为 ${changes[key].newValue}`);
}
});
5.3 标签页API
// 查询标签页
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
const currentTab = tabs[0];
});
// 创建新标签页
chrome.tabs.create({ url: 'https://example.com' });
// 更新标签页
chrome.tabs.update(tabId, { active: true });
// 执行脚本
chrome.scripting.executeScript({
target: { tabId: tabId },
func: () => {
// 在页面中执行的代码
}
});
5.4 通知API
chrome.notifications.create('id', {
type: 'basic',
iconUrl: 'icon.png',
title: '通知标题',
message: '通知内容'
});
6. 实战案例
案例1:网页内容提取器
manifest.json
{
"manifest_version": 3,
"name": "网页内容提取器",
"version": "1.0",
"permissions": ["activeTab", "scripting"],
"action": {
"default_popup": "popup.html"
}
}
popup.html
<!DOCTYPE html>
<html>
<body>
<h3>内容提取</h3>
<button id="extract">提取标题和链接</button>
<div id="output"></div>
<script src="popup.js"></script>
</body>
</html>
popup.js
document.getElementById('extract').addEventListener('click', async () => {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const results = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: () => {
// 提取页面所有链接
const links = Array.from(document.querySelectorAll('a'))
.map(a => ({
text: a.textContent.trim(),
href: a.href
}))
.filter(link => link.text && link.href);
return {
title: document.title,
links: links.slice(0, 10) // 前10个链接
};
}
});
const output = document.getElementById('output');
output.innerHTML = `
<h4>${results[0].result.title}</h4>
<ul>
${results[0].result.links.map(link =>
`<li><a href="${link.href}" target="_blank">${link.text}</a></li>`
).join('')}
</ul>
`;
});
案例2:自定义右键菜单
background.js
// 创建右键菜单
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "searchGoogle",
title: "使用Google搜索 '%s'",
contexts: ["selection"]
});
chrome.contextMenus.create({
id: "saveNote",
title: "保存选中文本",
contexts: ["selection"]
});
});
// 处理菜单点击
chrome.contextMenus.onClicked.addListener((info, tab) => {
switch (info.menuItemId) {
case "searchGoogle":
const query = encodeURIComponent(info.selectionText);
chrome.tabs.create({
url: `https://www.google.com/search?q=${query}`
});
break;
case "saveNote":
chrome.storage.local.get(['notes'], (result) => {
const notes = result.notes || [];
notes.push({
text: info.selectionText,
url: tab.url,
timestamp: new Date().toISOString()
});
chrome.storage.local.set({ notes });
});
break;
}
});
7. 调试与发布
7.1 调试技巧
- 弹出页面调试:右键点击扩展图标 → "检查弹出内容"
- 后台脚本调试:进入扩展管理页面 → 点击"service worker"链接
- 内容脚本调试:在网页开发者工具 → Sources → Content scripts
- 网络请求查看:开发者工具 → Network → 筛选扩展请求
7.2 控制台日志
// 不同组件的日志查看位置
console.log('Background:', message); // 后台脚本控制台
console.log('Content:', data); // 网页控制台
console.log('Popup:', info); // 弹出页面控制台
7.3 发布到Chrome网上应用店
-
准备工作
- 准备各种尺寸的图标(16x16, 48x48, 128x128, 512x512)
- 创建应用商店列表截图(1280x800或640x400)
- 撰写详细描述和宣传图
-
打包扩展
- 打开
chrome://extensions/ - 点击"打包扩展程序"
- 生成.crx文件和.pem私钥文件
- 打开
-
提交审核
- 访问Chrome开发者仪表板
- 支付一次性注册费$5
- 上传ZIP包并填写信息
- 等待审核(通常需要几天)
7.4 常见问题解决
-
权限被拒绝
- 检查manifest.json中的permissions
- 确保host_permissions正确配置
-
消息传递失败
- 检查组件是否已正确加载
- 使用try-catch捕获错误
-
存储数据丢失
- 使用chrome.storage替代localStorage
- 重要数据定期备份
-
性能优化
- 内容脚本使用延迟加载
- 避免频繁的storage操作
- 及时清理事件监听器
附录:实用资源
官方文档
开发工具
学习建议
- 从简单示例开始,逐步增加复杂度
- 充分理解Manifest V3的变化
- 注意安全性,避免恶意代码注入
- 考虑用户隐私,最小化权限请求
- 测试不同网站和场景的兼容性
提示:开发过程中,经常访问 chrome://extensions/ 页面进行加载、重载和调试。使用console.log()进行调试是最高效的方式之一。祝您开发顺利!