编写"谷歌扩大"便捷"自测"埋点上报信息是否正确
举荐我之前写的谷歌扩大入门&svelte入门文章:
记一次前端"chrome扩大"简略易懂的实战分享会(上)
记一次前端"chrome插件"根底实战分享会(倡议珍藏)(下篇)
聊聊Svelte.js技术它做了什么以及如何实现的(上)
聊聊Svelte.js技术它做了什么以及如何实现的(下)
背景
每次开发完我的项目的埋点性能后都须要进行埋点自测, 此时我只能通过在控制台的Network
上进行筛选, 因为埋点的申请参数是个"对象类型", 须要将传参逐一点开并且找到params
这个key, 然而params
是一个被json序列化的字符串, 须要进行JSON.parse(xxxxx.params);
, 而后再关上它外面的数组构造
因为可能是多个埋点信息一起上报所以JSON.parse
后是个数据, 最初还要将外面的十个固有参数过滤掉只看咱们新增的埋点参数。
上述过程很有法则所以能够形象成一个工具查找的逻辑, 那咱们能够把问题拆解成3步:
- (展现)有适合的界面不便显示你想要的申请数据。
- (获取)拦挡到你想要的申请。
- (解决)将申请的参数按固定规定解析, 剔除不须要查看的参数与父级。
- (配置)可配置哪些申请须要被监测。
当然不只是埋点
这个性能, 只有你有剖析api数据的需要都能够做相似的插件。
最终成果
一、模仿数据的定义
埋点上报数据我这里展现一个大略的数据结构, 大家依据业务自行调节, 假如上面的数据结构就是埋点上报api的上报参数
[ { events: [ { eventName: "事件名: 点击事件", params: '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn1", "new2":"nnnnnn2"}', xxxxxxxx: 1636179764881, xxxxxxx: 0, }, { eventName: "事件名: 勾销事件", params: '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn2", "new3":"nnnnnn3"}', xxxxxxxx: 1636179764881, xxxxxxx: 0, }, ], user: { userId: 123, userName: "lulu", }, header: { app_id: 999, os_name: "mac", os_version: "10_15_7", device_model: "Macintosh", language: "zh-CN", }, },];
- 传参自身是个"对象类型"
- 第一层次要是"埋点事件", "用户信息", "设施信息&更多"
- "events"是事件数组
- "eventName"事件名称, "params"外面是被"JSON序列化"的事件参数
- "params"里有一些咱们不必看的默认值, 因为每个埋点都会带一些像"门路信息"&"停留事件"&"用户操作门路"等等的默认信息, 这些信息不必咱们手动退出所以也就不必每次都看他的正确性。
- "new1, new2, new3"是咱们新退出的参数, 也就是咱们这次重点验证的参数
二、模仿埋点数据的收回
编写两个按钮负责上报埋点申请, 不便咱们后续的验证, 新建一个html文件:
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <button onclick="send(`https://zhangzhaosong1.com/`)">点击上报1</button> <button onclick="send(`https://zhangzhaosong2.com/`)">点击上报2</button> <script> function send(url) { fetch(url, { method: "post", headers: { "Content-Type": "application/json;charset=utf-8;", }, body: JSON.stringify([ { events: [ { eventName: "事件名: 点击事件", params: '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn1", "new2":"nnnnnn2"}', xxxxxxxx: 1636179764881, xxxxxxx: 0, }, { eventName: "事件名: 勾销事件", params: '{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx", "new1":"nnnnnn2", "new3":"nnnnnn3"}', xxxxxxxx: 1636179764881, xxxxxxx: 0, }, ], user: { userId: 123, userName: "lulu", }, header: { app_id: 999, os_name: "mac", os_version: "10_15_7", device_model: "Macintosh", language: "zh-CN", }, }, ]), }).then(() => {}); } </script> </body></html>
下面html外面次要做的工作是增加两个"按钮", 每次点击收回埋点的模仿上报的post申请, 每个按钮上报的不一样所以有两个按钮。
三、创立一个谷歌插件我的项目 & 定义图标
没看过基础课的同学肯定要先看看根底文章, 否则没法转换思维。
主文件
manifest.json
{ "manifest_version": 2, "name": "埋:更不便的察看埋点数据", "description": "更不便的察看埋点数据", "version": "0.1", "browser_action": { "default_icon": "images/logo.png" }}
上述的图标大家自由发挥哈
引入插件
四、定义控制台tab
在manifest.json文件外面减少
{ "manifest_version": 2, "name": "埋:更不便的察看埋点数据", "description": "更不便的察看埋点数据", "version": "0.1", "browser_action": { "default_icon": "images/logo.png" }, "devtools_page": "devtools/index.html" // 这句是新增的}
devtools/index.html
次要性能只是引入js文件
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <script src="./index.js"></script></body></html>
devtools/index.js
次要性能是创立tab
chrome.devtools.panels.create( "埋点验证tab, 还原埋点上报信息", null, "../panel/index.html", function () { console.log("自定义面板创立胜利!"); });
在panel/index.html
外面才是tab的内容区款式:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <div>创立胜利</div></body></html>
五、初始化svelte我的项目
tab外面的内容咱们懒得原生操作dom, 应用"react"框架有点重, 所以这次我抉择了"svelte框架", 具体它的益处能够看看我之前写的文章(文章放在文章头部了)。
初始我的项目
npx degit sveltejs/template devpanelcd ./devpanelyarn
咱们编辑一下 rollup.config.js
文件, 使得打包后的文件间接放入panel
文件夹里。
output: { sourcemap: false, format: "iife", name: "app", file: production ? "../panel/index.js" : "public/build/bundle.js", },
并且将panel
外面的index.html
文件的文件援用指向咱们的index.js文件
, 以及引入款式 <link rel="stylesheet" href="./bundle.css">
在这里运行命令yarn build
后的成果如下, 请点击刷新插件并且"F12"从新关上控制台:
开发时候在localhost:5000/
, 开发完打包就能够和插件一起上线了。
六、拦挡申请
外围性能就是拦挡申请, 让咱们应用onRequestFinished
api
chrome.devtools.network.onRequestFinished.addListener((res) => {})
下面的返回值res的数据格式如下图:
要害信息都有, 申请办法与url能够用来比对是否为须要拦挡的申请, 而咱们剩下的工作就是对"text"的解析了。
要留神的是, svelte
外面无奈读取到chrome
的值, 所以须要用if (chrome) {}
包裹起来, 所以在svelte外面开发时我应用的是mock数据调试。
七、解决数据
<script> const path = "https://zhangzhaosong.com/"; import getNowTime from "./getNowTime"; if (chrome) { let checkEvent = ""; let dataList = []; const baseKeyArr = [ "default1", "default2", "default3", "default4", "default5", "default6", "startTime", "endTime", ]; chrome.devtools.network.onRequestFinished.addListener((res) => { const req = res.request; if (req.method === "POST" && req.url === path) { const eventsArr = JSON.parse(req.postData.text); eventsArr.forEach((item) => { if (item.events) { item.events.forEach((event) => { const params = JSON.parse(event.params); const res = {}; for (let i in params) { if (!baseKeyArr.includes(i)) { res[i] = params[i]; } } dataList.unshift({ res, time: getNowTime(), eventName: event.eventName, }); dataList = dataList; }); } }); console.log("---", dataList); } }); }</script><main> <div>list</div></main><style></style>
baseKeyArr
这个数组外面是一些埋点默认的key
, 用来过滤掉咱们不关怀的值path
是要拦挡的申请地址, 当然也能够换成正则之类的getNowTime
获取以后的工夫
八、简略设计个款式
将下面失去的数组循环显示进去, 造成一个被拦挡的埋点事件的参数list:
<main> {#each Object.keys(dataList) as item} <div> <header> <span>{dataList[item].time} : </span> <span class="title">{dataList[item].eventName}</span> </header> <ul> {#each Object.keys(dataList[item].res) as key} <li> <span>{key} :</span> <span>{dataList[item].res[key]}</span> </li> {/each} </ul> </div> {/each}</main><style> .title { background-color: bisque; }</style>
九、过滤性能与革除性能
为了好用咱们能够增加一个过滤性能与革除性能, 这样查看起来更难受:
end
网站快卡炸了, 这次就是这样, 心愿与你一起提高。