0x00 先唠会嗑
这篇文章中提到的chrome插件原型,是为了采集某些网站的数据而制作的。
毕竟在浏览器窗口中采集比通过发送GET/POST请求分析响应结果、调用无头浏览器运行js、**数据加密接口来的更简单
具体代码不方便拿出来分享,只能聊一聊编写的思路。
0x01 流程图介绍
![]()
图上客户端代表了安装了chrome插件的chrome浏览器。
具体流程如下:
1.控制台通过websocket服务器给客户端下发任务。
2.客户端打开时,chrome插件自动连接websocket服务器获取任务。
3.客户端采集之后发送到websocket服务器。
4.websocket服务器把获取到的采集内容存储到DB中
0x02 chrome插件
因为具体部分不方便说,所以这里就总结一下这次chrome插件开发中遇到的问题。
background-script.js和content-script.js间无法实现消息传递
最开始打算websocket是在background-script.js中发起链接的,这样可以保持长连接不会受网页关闭的影响而断开。测试的时候已经实现了在background-script.js中连接websocket,但是在background-script.js和content-script.js的消息传递中遇到了问题,两者居然无法互相通信?
经过查阅,我在chrome的官方文档中找到了如何在两者之间建立长连接(不是指websocket)的方法,但我在chrome(v78.0.3904.108)中并未成功建立链接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var port = chrome.runtime.connect({name: "knockknock"}); port.postMessage({joke: "Knock knock"}); port.onMessage.addListener(function(msg) { if (msg.question == "Who's there?") port.postMessage({answer: "Madame"}); else if (msg.question == "Madame who?") port.postMessage({answer: "Madame... Bovary"}); });
chrome.runtime.onConnect.addListener(function(port) { console.assert(port.name == "knockknock"); port.onMessage.addListener(function(msg) { if (msg.joke == "Knock knock") port.postMessage({question: "Who's there?"}); else if (msg.answer == "Madame") port.postMessage({question: "Madame who?"}); else if (msg.answer == "Madame... Bovary") port.postMessage({question: "I don't get it."}); }); });
|
最后只能退而求其次,在content-script.js发起websocket链接。(在background-script.js建立的好处是ws链接更隐秘,如果是在content-script.js中建立则会在F12控制台network - ws 中显示出来)
另外推荐在content-script.js中加入对window.onbeforeunload的监听(离开页面事件),websocket服务端在客户端断开时也要做好异常处理。有时候直接刷新页面会导致websocket服务器因为异常断开而崩溃(但nodejs写websocket还是香!)
1 2 3
| window.onbeforeunload = function () { wsClient.close(); }
|
popup的生命周期
原本以为popup的生命周期和background-script一致。测试后才发现popup的生命周期是浏览器右侧插件小图标点击后,菜单显示到消失的这个过程。关于content-script、background-script、popup之间的关系,可以参考这篇文章:【干货】Chrome插件(扩展)开发全攻略
0x03 websocket
这里用的是node-websocket这个包,非常的简单易用。可以按自己的需求拓展,后面可能会尝试写一个基于这个包的websocket框架,到时候会再开一篇写发明轮子的过程hhh。
控制台和客户端的账号区分
控制台登入时,用户标识为admin。
客户端的用户标识则是 36进制(时间戳+ip(replace掉dot符)+随机数字(100000-999999)),一般情况下这样足够得出一个够短且唯一的标识,如果想要更小的碰撞几率就不断放大随机数字的区间即可。
先写到这吧,月底前会再发一篇记账webapp的开发日记,也没什么想说的,提前给大家拜个早年吧!