Chrome插件开发入门
最近学习了Chrome插件的开发,总体来说上手还是很容易的,因为浏览器插件本质上依旧是网页,写几个demo基本就了解了他的开发过程。
什么是Chrome插件
正如开头所说的,Chrome插件实际上就是一个网页,由HTML、CSS、JS、图片等资源组成,与网页不同的是,Chrome插件是用来增强浏览器功能的,同时它还有一套属于自己的开发规则和API。
每个插件都由不同的组件构成,这些组件大都包括background scripts,content scripts,options page,UI以及各种逻辑文件,当然,这些文件是否需要是根据插件的功能所决定的。
接下来我将通过开发一个获取页面图片并保存的插件来介绍如何开发一个Chrome插件。
获取页面上的图片
首先,我们需要一个目录来存放这个插件的各个文件。
创建manifest
manifest.json是一个Chrome插件必不可少的文件,它包含了你插件的所有信息。
{
"name": "获取图片",
"description": "获取页面上的所有图片",
"version": "1.0",
"manifest_version": 3
}
只要在目录中包含manifest.json,这个目录就可以被作为一个Chrome插件添加到Chrome当中。
- 在浏览器地址栏中输入
chrome://extensions,回车以打开浏览器的扩展程序界面 - 打开开发人员模式
- 点击
加载已解压的扩展程序,选择manifest文件所在的目录
这样我们就成功安装了一个扩展,接下来我们要在此基础上完善它。
用户界面
一个插件可以有多种形式的用户界面,这里我们选择弹出层作为用户界面,在插件根目录下创建一个popup.html,这个页面需要包含两个按钮分别用来触发获取图片和保存图片的事件,以及一个用来展示图片的盒子。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<style>
body,
img {
width: 400px;
}
</style>
</head>
<body>
<button id="get">获取</button>
<button id="save">保存</button>
<div id="app"></div>
</body>
</html>
注意,如果在popup.html中有中文出现,一定要在head标签中添加<meta charset="UTF-8" />,以防止出现乱码。
创建完成后,我们需要在manifest.json中声明该页面,以保证浏览器能够正确的读取到它。添加一个action对象,同时将popup.html设置为该对象的default_popup。
{
"name": "获取图片",
"description": "获取页面上的所有图片",
"version": "1.0",
"manifest_version": 3,
"action": {
"default_popup": "popup.html",
},
}
为了让我们的插件像个正经的插件,给他添加上图标。我们需要准备16x16、32x32、48x48以及128x128四种大小的图标图片,将它们放到目录中,之后将它们的路径写入manifest.json中。
{
"name": "获取图片",
"description": "获取页面上的所有图片",
"version": "1.0",
"manifest_version": 3,
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png",
"128": "/images/logo128.png"
}
},
}
为了让图标能够在扩展程序管理页面显示,我们还需要添加一个icons对象。
{
"name": "获取图片",
"description": "获取页面上的所有图片",
"version": "1.0",
"manifest_version": 3,
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png",
"128": "/images/logo128.png"
}
},
"icons": {
"16": "/images/logo16.png",
"32": "/images/logo32.png",
"48": "/images/logo48.png",
"128": "/images/logo128.png"
}
}
点击扩展程序管理页面中的更新按钮,即可看到添加完用户界面的插件信息了。
功能逻辑
之后我们要为插件添加它应有的功能——获取页面图片。
首先我们先简单梳理一下需求:
- 点击popup.html中的获取按钮,拿到当前页面的图片
- 点击popup.html中的保存按钮,将拿到的图片保存下来
实际上我们的插件与当前正在活动的页面并不是同一个页面,因此我们需要通过某种方式来将获取图片的js代码发送到当前活动页上,并且还需要这段js代码能够在获取到图片之后将图片发送到popup.html中。
这里我们就需要用到一开始提到的content scripts组件以及content script与popup之间通信的API。content scripts简单来说就是插入页面的脚本,虽说是插入页面的脚本,实际上它与页面原本的js是分割开的,双方不能获取到对方的变量、函数等内容。不过content scripts还是可以获取到dom的。
获取图片
首先添加一个content-script.js,这个脚本主要有两个功能,一是获取图片,二是监听popup传来的消息,然后将获取到的图片作为回信传回去。
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
// message的数据格式取决于发送时的数据
const { start } = message;
if (start) {
const images = document.getElementsByTagName('img');
const imgSrcList = Array.from(images).map((img) => img.src);
sendResponse(imgSrcList);
}
});
之后我们要在manifest.json中声明配置它
{
...
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"js/content-script.js"
]
}
]
}
matches声明了content scripts要注入的页面,<all_urls>表示所有页面,js属性声明了要注入的js脚本,除此之外还有css属性声明要注入的css代码、run_at属性声明注入时机等都可以在官方文档中找到。
之后添加一个popup.js为界面上的按钮注册点击事件,并在popup.html中引入它
let srcList;
const getImageBtn = document.getElementById('get');
getImageBtn.addEventListener('click', async () => {
// 获取当前活动页
chrome.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
let message = { start: true };
// 向content scripts发送消息
chrome.tabs.sendMessage(tab.id, message, (res) => {
srcList = Array.from(new Set(res));
// popup中展示图片
const imgList = srcList.map((src) => `<img src="${src}" />`).join('');
document.getElementById('app').innerHTML = imgList;
});
});
});
const saveImageBtn = document.getElementById('save');
saveImageBtn.addEventListener('click', () => {
// 保存图片
});
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<style>
body,
img {
width: 400px;
}
</style>
</head>
<body>
<button id="get">获取</button>
<button id="save">保存</button>
<div id="app"></div>
<script src="./js/popup.js"></script>
</body>
</html>
这里我们需要注意,插件要想和当前活动页面通信就需要首先获取它的tabId,而要获取当前活动页面的tabId则需要给予插件对应的权限,因此我们需要在manifest.json中声明所需要的权限。
{
...
"permissions": [
"activeTab"
]
}
完成后更新一下插件,然后打开想要获取图片的页面点击获取按钮即可(如果页面已经提前打开请刷新一下)
保存图片
js可以通过a标签设置href和download属性来实现批量保存图片,但是这里我们要通过调用chrome的download API来实现。
...
saveImageBtn.addEventListener('click', () => {
chrome.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
if (!srcList) {
document.getElementById('app').innerHTML = '未获取图片';
return;
}
srcList.forEach((src) => {
chrome.downloads.download({
url: src,
});
});
});
});
与获取活动页面相同,download API同样也需要获取权限
{
...
"permissions": [
"activeTab",
"downloads"
]
}
这样一个获取当前页面图片的插件就完成了。
参考文章
Chrome插件开发入门的更多相关文章
- Chrome插件开发入门(二)——消息传递机制
Chrome插件开发入门(二)——消息传递机制 由于插件的js运行环境有区别,所以消息传递机制是一个重要内容.阅读了很多博文,大家已经说得很清楚了,直接转一篇@姬小光 的博文,总结的挺好.后面附一 ...
- [Chrome插件开发]001.入门
Chrome插件开发入门 Chrome扩展文件 Browser Actions(扩展图标) Page Actions(地址栏图标) popup弹出窗口 Background Pages后台页面 实战讲 ...
- vue.js 初体验— Chrome 插件开发实录
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 作者:陈纬杰 背景 对于经常和动画开发打交道的开发者对于Animate.css这个动画库不会陌生,它把一些常见 ...
- chrome插件开发-消息机制中的bug与解决方案
序言 最近开发chrome插件,涉及到消息传递机时按照教程去敲代码,结果总是不对.研究了大半天终于找到原因,现在记录下. 程序 插件程序参考官网 chrome官网之消息传递机制, 不能FQ的同事也可以 ...
- Chrome插件开发,美化网页上的文件列表。chrome-extension,background
上一篇文章 通过“content-scripts”的方式向页面注入js和css来美化页面,但是有一个弊端:一旦配置好需要注入的页面,之后如果这个页面地址以后发生变化,或者要新加一些URL进来,那么得修 ...
- Chrome插件开发,美化网页上的文件列表。chrome-extension,content-scripts
趁着2018年还剩最后几天,发几篇博客,荒废太久了,惭愧. 最近也是需求驱动,研究了下Chrome插件开发.来看一下我们公司运维提供的日志查看页面 所有项目的日志都参杂在一起,每次去找都很痛苦.慢慢发 ...
- chrome插件开发学习(一)
两个不错的网址: 360chrome插件开发文档:http://open.chrome.360.cn/extension_dev/manifest.html 图灵 chrome插件开发于应用 电子书: ...
- 入门chrome插件开发教程和经验总结,一篇就搞掂!
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_44244857/articl ...
- Vue插件开发入门
相对组件来说,Vue 的插件开发受到的关注要少一点.但是插件的功能是十分强大的,能够完成许多 Vue 框架本身不具备的功能. 大家一般习惯直接调用现成的插件,比如官方推荐的 vue-router.vu ...
随机推荐
- 未来,Baccarat将如何拓展生态版图?
Baccarat最近几度冲上DeFi版面的热搜,一是因为BGV价格不断的上涨,二是因为生态建设者的不断涌入.可以说,当下的Baccarat,实在是太火爆了.那么在未来,Baccarat还将会持续火爆吗 ...
- [转]基于ROS平台的移动机器人-4-通过ROS利用键盘控制小车移动
原文出处: https://blog.csdn.net/Forrest_Z/article/details/55002484 准备工作 1.下载串口通信的ROS包 (1)cd ~/catkin_ws/ ...
- JVM系列(四):java方法的查找过程实现
经过前面几章的简单介绍,我们已经大致了解了jvm的启动框架和执行流程了.不过,这些都是些无关痛痒的问题,几行文字描述一下即可. 所以,今天我们从另一个角度来讲解jvm的一些东西,以便可以更多一点认知. ...
- winform导出excel
public void AllDataSetToExcel(DataSet ds) { string saveFileName = ""; bool fileSaved = fal ...
- 边缘计算k8s集群之SuperEdge
什么是边缘计算? 边缘计算,是指在靠近物或数据源头的一侧,采用网络.计算.存储.应用核心能力为一体的开放平台,就近提供最近端服务.其应用程序在边缘侧发起,产生更快的网络服务响应,满足行业在实时业务.应 ...
- 使用Prometheus搞定微服务监控
最近对服务进行监控,而当前监控最流行的数据库就是 Prometheus,同时 go-zero 默认接入也是这款数据库.今天就对 go-zero 是如何接入 Prometheus ,以及开发者如何自己定 ...
- 破解MySQL库user表hash密码
目录 得到用户名和密码 hash 带*和不带*的区别 破解hash 在线工具 Hashcat 实验环境 select version(); 得到用户名和密码 hash mysql安装好就会默认生成图中 ...
- c++函数指针说明
下面随笔说明函数指针用法. 函数指针的定义: 定义形式: 存储类型 数据类型 (*函数指针名)() 含义: 函数指针指向的是程序代码存储区 函数指针的典型用途-----实现函数回调 通过函数指针调用的 ...
- ELK----elasticsearch7.10.1安装配置
环境: vmware centos7 1.下载适合自己的es版本 https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-1 ...
- 定西+简单dp
定西 ECNU-3531 #include<iostream> #include<cstdio> #include<algorithm> #include<c ...