如何写一个简易的chrome插件
如何写一个简易的chrome插件
推荐阅读
https://developer.chrome.com/extensions/getstarted
推荐阅读官方文档,本文只做简单的演示。
本文图片之类链接打不开,可直接科学上网走外链,参考 原博文
概念介绍
基本配置
- manifest.json
可以类比 AndroidManifest
,几乎所有的项目都会有一个主配置文件,用来配置全局的基本信息和属性来保证系统的基本启动运行,该文件为 chrome plugin
主配置文件。
基于浏览器插件考虑所占体积这个特性,几乎所有关键的配置属性信息都可以在此找到,除了名称,版本等必要的信息,
尤为值得关注的几个属性就是
background
改配置属性决定项目启动时会去扫描哪些 js 文件, 然后以此决定需要监听的事件
1 | "background": { |
permission
该属性为权限属性,这个的重要性不必多说,上面的属性注册事件监听时往往需要依赖大量的api,而这些api的权限就依赖于这个permission
属性
1 | "permissions": ["storage"] |
browser_action
权限和动作都有了,剩下的显然就是渲染的模板文件了,该属性决定了回显需要的大多数配置,包括插件的图标,点击插件时显示的页面等
1 | "browser_action": { |
重点注意
上面的图中可以看到,插件是基于
message
来互相通信的, 这个message
后面再说Chrome
不允许将JavaScript
代码段直接内嵌入HTML文档 (inline-script也是被禁止)
所以我们需要通过外部引入的方式引用JS文件
所以所有元素的事件都需要使用JavaScript代码进行绑定
如果你没有使用一个拥有强大选择器的库(jQuery), 最好给需要绑定事件的元素分配一个id以便进行操作
"manifest_version": 2
, 这个写 2 吧, 别问为啥contentscript.js
这个决定了用户所在的界面操作,emmmm, 就简单理解为通过插件隐性的操作用户的浏览界面,这个这么说明显风险很大,摆明了就是注入 js 搞事的,可以参考个例子: 永远点不到的百度按钮 注:文章是很久以前瞎抄的图灵社区来着,可能乱七八糟的,就看个效果就行了,本文只是简单的开发,不会使用各类复杂的属性前面提到的background 属性,有两个可能不是很必要使用的值,一个是
page
, 这个是后台配置属性文件,一般需要构建后台页面时才需要。 而persistent
属性定义了常驻后台的方式(默认为true)——当其值为true时,表示扩展将一直在后台运行,无论其是否正在工作;当其值为false时,表示扩展在后台按需运行,这就是Chrome后来提出的 Event Page, 这个说白了就是按需运行,少耗点内存,不过少耗有什么用呢,chrome嘛,大家都懂的。
实战
开发目标
实现一个访问日志记录,用来记录当前浏览器发出的请求
开发日志 项目地址
- 先从基本配置开始, 如下所示
1 | { |
我们定义了这个插件的一些基本属性,包括它的名字,描述,版本号,申请权限(这里申请了debugger权限,因为这个权限级别比较高,可以方便开发使用,实际开发是不推荐使用的,另一个tabs权限自然就是tab页相关了), 以及为其注册了一个后台 js 用来主监听,和默认使用的插件 icon
The chrome.debugger API serves as an alternate transport for Chrome’s remote debugging protocol. Use chrome.debugger to attach to one or more tabs to instrument network interaction, debug JavaScript, mutate the DOM and CSS, etc. Use the Debuggee tabId to target tabs with sendCommand and route events by tabId from onEvent callbacks.
- 接下来我们在
background.js
中注册基本的监听器
1 | chrome.browserAction.onClicked.addListener(function(tab) { |
上述使用的api都可以在文末的手册链接中找到,这里只做简单的描述,第一个
browserAction.onClicked
会根据你是否已经popup
(就是你点图标后弹出的小窗) 来决定是否触发, 这个监听器会监听到一个 tabId 从而定位目标的tab
页。接下来使用
chrome.debugger.attach
使用这个将debug
目标挂载上,这个attach
接受三个参数, debuggee 对象, 版本号,和一个回调函数,挂载成功时会触发该回调,失败时会采用类似C
的异常处理方式,也就是用全局变量去set异常记录。我们在
debugger
成功挂载上目标对象后,创建我们的主页面,开始我们真正的业务代码开发
- 业务相关
- 前面提到过
chrome
,chrome
不允许直接将js
嵌入文档,所以都是外部引入js
的,我们这里不引入其他工具型js
了,直接使用基本的id
去锁定目标element
来操作,可以看到总共使用了三部分,一个按钮,用作请求日志的导出,一个container
, 用做基本的渲染展示。
1 | <html> |
- 然后我们在
header.js
中,通过load event
, 为页面加载完成后绑定回调方法,在方法中首先使用sendCommand
向目标tab
页发送指令Network.enable
来启用web
请求tracking
。在此之后我们开启debugger
事件监听,通过监听的第二,三个参数可以获取到大部分了想要的数据了(二三个参数分别是remote debugging protocol
的方法名和方法参数), 至此所有的资源都准备好了,接下来就是依赖这些资源自行进行开发了
1 | var tabId = parseInt(window.location.search.substring(1)); |
- 最后,以我写的简单小插件作为最后 onEvent 监听器样例吧,代码风格很糟,草草起手,加上我专项是后端,前端的原生
js
并不熟悉,所以仅仅加了注释方便参考,前面核心的地方都说了,后面这一点其实可有可无(我就是单纯的根据url进行了个前缀分类然后导出了csv
,而也可以按照http header的状态码(比如403, 懂的都懂)或者任意信息做个类似的),大家按自己的需求开发即可【Dev tools network 的 abilities 都有了还有啥做不出来 -_-】
1 | function onEvent(debuggeeId, message, params) { |
- 附一张截图
推荐查询手册
懒推广
插件怎么写都说了,以后应该也不会写类似的文章,这里就顺便说下我自己用的一些插件,老实说并不常用,但是偶尔用上就莫名被爽到。
https://github.com/ReZeroS/request-record
This post is used to explain how to write the plugin: request-record.
I got a mission this week to record all api from function requests in our system. I have finished it, but I still wanna to write a plugin to simplify this work. Well, it maybe does not work well, so just write for fun.
First step: bulid the setting
Most project should be included a setting file which is used to describe the whole project base setting such like common properties, version number, etc…
Chrome extension got this file called manifest.json
.
1 | { |
The permissions
field tells the permissions it required and background
field tells the background scripts should be registered.
If u still don’t know what is the above mean, u can just write it down and skip this.
Second step: render the page
Since we finished the first step, the only info we can infer to is the background
field tell background.js
, let’s write it.
1 | chrome.browserAction.onClicked.addListener(function(tab) { |
Chrome support chrome
object to provide the api for developer to access the browser. And u can see them all from here. The listener we registered will fire when a browser action icon is clicked while does not fire if the browser action has a popup. We use the listener to capture the tab and pass it to debugger which can attach to it to instrument network interaction, debug JavaScript, mutate the DOM and CSS, etc. Use the Debuggee tabId to target tabs with sendCommand and route events by tabId from onEvent callbacks.
After we bind the chrome tab we can write the real work code and got the error message at runtime.
Third step: build the app
The follow template shows how to bind listener to the window we created last step and capture the web request.
The Network.enable
varible which defined by the remote debugging protocol could enable network tracking, and then network events will be delivered to the client.
1 | var tabId = parseInt(window.location.search.substring(1)); |
onEvent
function got three params: debuggeeId, message, params
, u can use them to write what u want.
Here I wanna to record the request log, so I intercept at the requestWillBeSent
, and get the request from the params, get the tab url by using chrome.tabs.query
.
Last step: load your package
After last three steps, we can open the extension tab and load from unzip folder which we created, then u can see it.
- Post title:如何写一个简易的chrome插件
- Post author:ReZero
- Create time:2020-03-07 14:09:00
- Post link:https://rezeros.github.io/2020/03/07/init-chrome-plugin/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.