最近学习了一些前端知识,准备找点方向和项目在工作之余练练手。偶然间被 ChatGPT 提醒,觉得 Chrome 拓展开发是一个非常不错的方向。
Chrome 拓展是扩展浏览器功能的小程序,用户可以通过 Chrome Web Store 下载和安装。这些拓展能够增强浏览器的性能和用户体验,例如广告拦截、实时翻译、任务管理、笔记记录等。插件还提供自定义功能,使用户能够根据个人喜好调整浏览器外观和书签管理。同时,安全插件可以保护用户隐私和数据安全,开发拓展帮助开发者更高效地调试代码。跨平台同步功能使得用户可以在不同设备上享有一致的浏览体验。Chrome 应用市场丰富多样,满足各种需求。
优势
在我看来,Chrome
拓展有一下几点好处:
- 操作简单快捷。相比较普通的
Web
页面,拓展可以更快直达用户,免去跳转切换的繁琐手续。配合快捷键更是如虎添翼,直上云霄。 - 开发成本低。
Chrome
拓展开发只需要创建符合Chrome
要求的目录即可。简单的一键式直达功能不需要工程化,直接一两个方法解决。前端代码完全可以比照Web
端编写,甚至代码拿来即用,兼容性非常好。 - 开发效率高。据我自己体验,
Chrome
拓展的页面相对简单和独立,对于大量功能性页面,不需要太多交互设计,大大降低了开发难度,提升开发效率。对于一个前端小白的我来说,跟 ChatGPT 对话就能完成类似Postman
单页面的开发。甚至还能微调CSS
提升美观程度。
还有一个不咋上的台面的原因,就是可以直接抄别人的代码。比如我需要内置一个历史页面的管理功能,直接去 Chrome
商店下载一个拓展,然后发动抄能力,把源码抄过来即可,直呼过瘾。我已经在实践项目中抄了 3 个别人插件的源码,其中复活了一个由于未及时适配 Manifest V3
而被下架的插件,功能就是防止浏览器窗口关闭最后一个标签时会关闭整个窗口,有兴趣的可以私聊发源码交流。
下面正式进入正题,如何开发 Chrome
拓展。
准备
首先你需要具备一些知识:HTML
、CSS
、 JavaScript
等。
其次需要了解 Chrome
拓展开发规范和 API。
最后你需要一件趁手的兵器,我用的 Webstorm
。
第一步
首先需要一个 manifest.json
文件。manifest.json
文件是 Chrome 扩展的配置文件,定义了扩展的基本信息、权限和功能。下面是一个简单的示例:
{
"manifest_version": 3,
"name": "FunTester Extension",
"version": "1.0",
"description": "This is a simple Chrome extension example.",
"icons": {
"48": "icon48.png",
"128": "icon128.png"
},
"permissions": [
"tabs",
"storage"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": "icon48.png"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"web_accessible_resources": [
{
"resources": ["content.js"],
"matches": ["<all_urls>"]
}
]
}
以下是其主要功能的简介:
-
基本信息:
- manifest_version:指定清单文件的版本,目前最新版本是 3。
- name:扩展的名称。
- version:扩展的版本号。
- description:扩展的简短描述。
- icons:定义扩展的图标,可以指定不同尺寸的图标。
-
权限:
- permissions:列出扩展需要的权限,例如访问标签页、存储等。这决定了扩展可以访问的浏览器功能和用户数据。
-
后台脚本:
-
background:定义后台脚本,在 manifest_version 3 中使用
service_worker
。后台脚本在浏览器启动时运行,管理扩展的生命周期和处理事件。
-
background:定义后台脚本,在 manifest_version 3 中使用
-
浏览器动作:
- action:定义扩展图标的默认行为,如点击图标时弹出的页面(popup),可以设置默认弹出页面和图标。
-
内容脚本:
- content_scripts:定义内容脚本,这些脚本将注入到匹配的网页中运行。内容脚本可以修改网页内容或监听网页事件。
-
可访问资源:
- web_accessible_resources:定义扩展中可以被网页访问的资源,例如内容脚本或图标。这使得网页能够访问扩展内的特定文件。
通过配置 manifest.json
文件,可以定义和控制 Chrome 扩展的各种功能和行为,包括用户界面、后台处理、网页内容修改和权限管理。这使得开发者能够创建功能丰富且安全的浏览器扩展。
以上信息建议去官方查看,我就是因为版本 V2
教程耽误了好一阵子功夫。
常用功能
popup 页面
在 Chrome 扩展中,popup 页面是指当用户点击扩展图标时弹出的界面。这个界面通常用于提供用户交互或展示信息。Popup 页面由一个 HTML 文件组成,可以包含 JavaScript 和 CSS 来实现其功能和样式。
popup 页面配置方式如下:
{
"manifest_version": 3,
"name": "FunTester Extension",
"version": "1.0",
"description": "This is a simple Chrome extension example.",
"action": {
"default_popup": "popup.html",
"default_icon": "icon48.png"
},
// 其他配置项...
}
这是一个简单的 popup 页面:
<!DOCTYPE html>
<html>
<head>
<title>Popup</title>
<style>
body {
width: 300px;
height: 200px;
font-family: Arial, sans-serif;
padding: 10px;
}
button {
margin-top: 20px;
}
</style>
</head>
<body>
<h1>Hello, World!</h1>
<p>This is a simple popup example.</p>
<button id="myButton">Click me</button>
<script src="popup.js"></script>
</body>
</html>
不清楚是什么版本开始,或者一直就这样。Chrome
扩展的安全性设计确实不允许在 HTML
页面中直接使用 JavaScript
代码来加载或执行扩展的功能。Chrome 扩展通过内容安全性策略来限制可以在页面上执行的脚本。这意味着扩展不能简单地通过内联 <script>
标签或通过 document.write()
插入的脚本来执行。这是为了防止恶意代码的执行和保护用户的安全。所以都是写在另外的 js
文件当中。
假如我们想给这个 myButton
添加一个 onClick
事件的处理方法,可以在 popup.js
中添加下面的代码:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('myButton').addEventListener('click', function() {
alert('Button clicked!');
});
});
background
background.js
文件是 Chrome
扩展的后台脚本,用于处理长期运行的任务、事件和状态管理。它在浏览器的后台运行,并且在浏览器启动时加载。对于 manifest_version 3
,使用 service_worker
作为后台脚本。
下面是配置方法:
{
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
// 其他配置项...
}
而在 V2
当中是这么配置的:
{
"manifest_version": 2,
"background": {
"scripts": ["background.js"],
"persistent": false
},
// 其他配置项...
}
顾名思义,background.js
就是作为背景存在,无论当我们在哪个页面上都会被加载。在 manifest_version 3
中,通过在 manifest.json
文件中定义 background
部分并引用 background.js
作为服务工作者,可以配置后台脚本来处理扩展的安装事件、消息传递、浏览器事件监听、持久存储、定时任务和网络请求。通过这种方式,可以在后台脚本中实现复杂的逻辑和状态管理,同时与其他扩展组件进行通信。
下面是 background.js
主要的功能演示:
1. 处理安装事件
在扩展安装或更新时执行一些初始化操作:
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
console.log("Extension installed");
// 初始化一些数据
chrome.storage.local.set({initialized: true});
} else if (details.reason === 'update') {
console.log("Extension updated to version " + chrome.runtime.getManifest().version);
}
});
2. 消息传递
监听和处理来自内容脚本(content scripts)、弹出页面(popup)和其他部分的消息:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "GREETINGS") {
console.log("Received message from", sender.tab ? "content script" : "popup", ":", message.payload);
sendResponse({message: "Hello from background script"});
}
});
3. 浏览器事件监听
监听浏览器的各种事件,例如标签页更新:
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete') {
console.log("Tab updated: ", tabId);
// 在更新的标签页中执行一些操作
}
});
4. 持久存储和同步
使用 Chrome
存储 API 在浏览器关闭时保持数据持久化:
// 存储数据
chrome.storage.local.set({key: 'value'}, () => {
console.log('Value is set to value');
});
// 获取数据
chrome.storage.local.get(['key'], (result) => {
console.log('Value currently is ' + result.key);
});
我们还可以将数据存储到云端,方便跨设备同步:
// 存储数据到同步存储
chrome.storage.sync.set({key: 'value'}, () => {
console.log('Value is set to value');
});
// 获取同步存储中的数据
chrome.storage.sync.get(['key'], (result) => {
console.log('Value currently is ' + result.key);
});
// 删除同步存储中的数据
chrome.storage.sync.remove(['key'], () => {
console.log('Value is removed');
});
// 清空所有同步存储数据
chrome.storage.sync.clear(() => {
console.log('All sync storage data is cleared');
});
5. 定时任务
设置定时器来定期执行任务:
setInterval(() => {
console.log("Periodic task running...");
// 执行定期任务
}, 60000); // 每分钟运行一次
6. 网络请求
发起网络请求,处理数据,并与服务器通信:
function fetchData() {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error fetching data:', error));
}
// 定期获取数据
setInterval(fetchData, 3600000); // 每小时运行一次
content_scripts
在 Chrome
扩展中,content.js
是内容脚本,用于在匹配的网页上执行 JavaScript 代码。内容脚本可以修改网页的 DOM
结构,与页面进行交互,并在浏览器页面加载时注入执行。
配置方法如下:
{
"manifest_version": 3,
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
假如我想在页面 body
中添加一个元素,可以在 content.js
中添加以下代码:
console.log("Content script loaded");
// 在页面 DOM 加载完成后执行操作
document.addEventListener('DOMContentLoaded', function() {
// 在页面中插入一个 div 元素
const div = document.createElement('div');
div.textContent = 'This content is injected by Chrome extension.';
document.body.appendChild(div);
});
Chrome
扩展中的 content.js
主要功能包括:
- DOM 操作:修改页面的 DOM 结构,例如插入、删除或修改元素。
- 事件监听:监听页面上的各种事件,如点击、输入、滚动等,以响应用户操作。
- 与页面交互:与页面上的元素进行交互,获取或修改它们的内容、属性和样式。
- 数据注入:在页面加载时向页面注入自定义的 HTML、CSS 或 JavaScript,改变页面的外观或行为。
- 内容修改和过滤:根据特定规则修改页面内容,过滤广告、隐藏特定元素或修改网页样式。
-
消息传递:与扩展的其他部分(如后台脚本
background.js
、弹出页面popup.js
)进行消息传递和通信。 - 数据采集和分析:收集页面上的数据,进行分析或发送到后台进行处理。
- 页面状态监控:监控页面的加载状态和变化,执行相应的操作或显示加载状态。
- 与第三方服务集成:与网页上的第三方服务或 API 进行集成和交互,获取数据或执行操作。
右键菜单
在 Chrome
扩展中,右键菜单(Context Menu
)是指用户右键点击浏览器页面或特定元素时弹出的菜单选项。开发者可以通过 Chrome 扩展来添加自定义的右键菜单选项,以提供更多的功能和交互性。
若想使用,需要在权限当中添加 contextMenus
内容,如下:
"permissions": [
"contextMenus"
],
我们通常会把创建右键菜单的方法放到 background
当中,这样就能一直运行。下面是添加右键菜单以及监听时间的代码演示:
// 创建一个右键菜单项
chrome.contextMenus.create({
id: "myContextMenu",
title: "Do Something",
contexts: ["page", "selection", "link"]
});
// 监听右键菜单点击事件
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "myContextMenu") {
console.log("Context menu item clicked:", info);
// 执行相应的操作,例如发送消息到 content script 或执行后台任务
}
});
使用 chrome.contextMenus.create
方法创建右键菜单项。使用 chrome.contextMenus.onClicked
监听菜单项点击事件。