# Chorme浏览器扩展开发
# 前言
# 相关链接
# 开发步骤
开发一个Chrome扩展需最近简单的需要下面几个步骤:
- 创建一个
manifest.json文件,用于描述扩展的元数据和行为。 - 创建一个
background.js文件,用于处理扩展的后台逻辑。 - 创建一个
popup.html文件,用于显示扩展的弹出窗口。 - 创建一个
popup.js文件,用于处理弹出窗口的逻辑。 - 创建一个
content.js文件,用于处理网页内容的逻辑。
manifest.json文件是配置文件,用于描述扩展的元数据和行为。它包含了扩展的名称、版本号、描述、图标、权限等信息。一个简单的manifest.json文件如下:
{
"manifest_version": 2, // 必须 版本号
"name": "My Extension", // 必须 扩展名称
"version": "1.0", // 必须 版本号
"description": "This is my extension",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"tabs",
"http://*/*",
"https://*/*"
],
"browser_action": {
"default_icon": "icon48.png",
"default_popup": "popup.html"
}
}
background.js文件是扩展的后台脚本,用于处理扩展的后台逻辑。它可以在扩展启动时运行,也可以在用户触发特定事件时运行。
popup.html文件是扩展的弹出窗口,用于显示扩展的界面。它可以在用户点击扩展图标时显示,也可以在用户触发特定事件时显示。
popup.js文件是弹出窗口的逻辑脚本,用于处理弹出窗口的交互逻辑。它可以在用户点击弹出窗口中的按钮时运行,也可以在用户输入文本时运行。
popup.html 和 popup.js主要控制的弹框如下:

content.js文件是扩展的内容脚本,用于处理网页内容的逻辑。它可以在用户访问特定网页时运行,也可以在用户触发特定事件时运行。
将我们的文件上传到Chrome浏览器,打开浏览器,点击扩展,选择加载已解压的扩展程序,选择我们创建的目录,即可使用我们的扩展。

# 调试
每次代码更新我们可以刷新我们的扩展进行更新。

调试后台程序我们需要点开扩展详情点击 Service Worker 进行调试(调试background.js)

调试popup.html和popup.js我们可以直接在弹框中右键选择调试工具。

# 常见操作
# 弹窗Popup
编写可以通过popup.html和popup.js来创建一个弹框,弹框的样式可以自定义,也可以通过manifest.json来配置,如下:
{
"manifest_version": 2, // 必须 版本号
"name": "My Extension", // 必须 扩展名称
"version": "1.0", // 必须 版本号
"description": "This is my extension",
"browser_action": {
"default_icon": "icon48.png",
"default_popup": "popup.html"
}
}
然后我们创建一个popup.html文件,如下:
<!DOCTYPE html>
<html>
<head>
<title>My Extension</title>
<style>
body {
width: 200px;
height: 200px;
background-color: #f1f1f1;
font-family: Arial, sans-serif;
}
button {
width: 100%;
height: 50px;
background-color: #4CAF50;
color: white;
border: none;
font-size: 16px;
}
</style>
</head>
<body>
<button id="myButton">Click me!</button>
<script src="popup.js"></script>
</body>
</html>
然后我们创建一个popup.js文件,如下:
console.log('Hello, world!');
document.getElementById('myButton').addEventListener('click', function() {
alert('Hello, world!');
});
# 侧边栏
侧边栏的创建和弹框类似,只是侧边栏的配置文件如下:
{
// ...
// 设置侧边栏
"sidebar_action": {
"default_icon": "icon48.png",
"default_panel": "sidebar.html"
}
}
打开侧边栏可以按下面操作

除了我们手动去触发打开侧边栏,我们还可以通过代码来触发侧边栏的打开和关闭,如下:
// 打开侧边栏
chrome.sidebarAction.open();
// 指定tab页打开侧边栏
chrome.sidebarAction.open({tabId: tabId});
// 关闭侧边栏
chrome.sidebarAction.close();
# 操作DOM
对于页面中的DOM操作我们可以通过content.js来操作DOM,如下:
console.log('Hello, world!');
document.body.style.backgroundColor = 'red';
document.getElementById('myButton').addEventListener('click', function() {
alert('Hello, world!');
})
在配置文件中引入该脚本
{
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
# 存储功能
chrome.storage API 提供了两种类型的存储方式:同步存储(chrome.storage.sync)和本地存储(chrome.storage.local),同步存储允许用户在不同设备之间同步数据,而本地存储则仅限于当前设备使用
// 读取本地存储
chrome.storage.sync.get(['key'], function(result) {
console.log(result.key);
});
// 写入本地存储
chrome.storage.sync.set({key: 'value'}, function() {
console.log('Value is set to ' + 'value');
});
对于cun态存储,Chrome 浏览器限制了存储的大小:
- 对于同步存储(
chrome.storage.sync),单个扩展程序最多可以存储 512KB 的数据; - 对于本地存储(
chrome.storage.local),单个扩展程序最多可以存储 5MB 的数据
注意
对于localStorage可以在背景脚本或内容脚本中直接调用相关方法,但是请注意,localStorage的数据隔离是基于域名的,而chrome.storage 是基于插件级别的。
对于其它数据持久化方案,我们可以使用IndexedDB,WebSQL或者云存储功能。
IndexedDB是一种在浏览器中存储大量结构化数据的技术,它允许我们存储大量数据,并且可以异步访问,不会阻塞主线程。 列子:WebSQL是一种在浏览器中存储大量结构化数据的技术,它允许我们存储大量数据,并且可以异步访问,不会阻塞主线程。
# 通信
这里通信有两种类型 短连接和 长连接。
# 短连接通信
短连接通信可以使用chrome.runtime (opens new window) 或 tabs.sendMessage (opens new window) 两个api来完成。
chrome.runtime (opens new window) API 提供了扩展程序和浏览器之间的通信功能,我们可以使用 chrome.runtime.sendMessage 和 chrome.runtime.onMessage 方法来发送和接收消息。
// 在内容脚本中 content.js
document.getElementById('btn').addEventListener('click', function() {
console.log('Button clicked!');
// 发送消息给后台脚本
chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
// 接收后台返回的消息
console.log(response.callback);
});
})
// 在后台脚本中 background.js 接收消息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// request:发送过来的消息对象
// sender:发送消息的页面对象,
// sendResponse:返回消息函数
console.log("request",request);
console.log("sender",sender);
console.log("sendResponse",sendResponse);
// 返回消息
sendResponse({callback: "监听返回消息"});
})
使用 chrome.tabs API 可以在扩展程序和页面之间进行通信,我们可以使用 chrome.tabs.sendMessage 和 chrome.runtime.onMessage 方法来发送和接收消息。
chrome.tabs.sendMessage(
tabId: number,
message: any,
options?: object,
callback?: function,
)
# 长连接通信
长连接通信是指在两个页面之间建立持久的连接,然后使用这个连接来交换数据。长连接通信可以使用:
runtime.connecttabs.connect页签之间的长连接
长连接在建立是会创建Port对象,然后通过Port对象来发送和接收消息。
// 在内容脚本中 content.js
var port = chrome.runtime.connect({name: "myConnection"});
// 发送消息给后台脚本
port.postMessage({greeting: "hello"});
// 监听返回消息
port.onMessage.addListener(function(msg) {
console.log(msg.farewell);
});
// 在后台脚本中 background.js
chrome.runtime.onConnect.addListener(function(port) {
console.log(port.name); // myConnection
port.onMessage.addListener(function(msg) {
console.log(msg.greeting);
port.postMessage({farewell: "goodbye"});
// 关闭连接, 也
port.disconnect();
});
});
如果一个connect呼叫在接收方的一端导致多个端口,并且disconnect()在这些端口中的任何一个上都被调用,那么该onDisconnect事件仅在发送方的端口上触发,而不在其他端口上触发。
# 事件监听
chrome.tabs API 提供了监听和操作浏览器标签页的功能,我们可以使用 chrome.tabs.onUpdated 和 chrome.tabs.onRemoved 方法来监听标签页的更新和移除事件。
// 在后台脚本中 background.js
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
console.log('Tab updated:', tab);
});
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
console.log('Tab removed:', tabId);
});
# 获取当前页面信息
chrome.tabs API 提供了获取当前页面信息的功能,我们可以使用 chrome.tabs.query 方法来获取当前标签页的信息。
// 在后台脚本中 background.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
console.log('Current tab:', tabs[0]);
});
# 获取当前页面URL
// 在后台脚本中 background.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
console.log('Current tab URL:', tabs[0].url);
});
# 获取当前页面标题
// 在后台脚本中 background.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
console.log('Current tab title:', tabs[0].title);
})
# ManifestV3 配置文件
{
//插件的manifest版本,此值应为3。
manifest_version:"",
//插件的名称
name:"",
// 插件的版本号。
version: "",
// 插件的描述。
description: "",
// 一个对象,其键是图标的像素尺寸,值是对应的图标文件路径。
icons: {},
// 一个对象,定义了扩展的默认图标,弹出窗口等。
action: {},
// 定义了扩展的背景服务工作线程。
background: {},
// 一个数组,定义了扩展的内容脚本。
content_scripts: [
{
// 内容脚本的匹配规则。
matches: [],
// 内容脚本的文件路径。
js: [],
// 内容脚本注入的CSS文件路径。
css: []
}
],
// 扩展的内容安全策略。
content_security_policy: "",
// 一个数组,包含了扩展请求的权限列表。
permissions: [],
// 一个数组,包含了扩展请求访问的主机权限列表。
host_permissions: [],
// 一个数组,列出了可以被通过web请求访问的资源。
web_accessible_resources: [],
// 允许扩展通过消息传递API连接到其他扩展或应用。
externally_connectable: {},
// 定义了扩展的选项页面。
options_page: "",
// 定义了扩展的选项页面。
options_ui: {},
// 一个对象,定义了扩展的快捷键命令。
commands: {},
// 定义了扩展的开发者工具页面。
devtools_page: ""
}
← Vue3-初识