为什么需要网络拦截工具
通常我们会遇到这样的场景:
- 线上一个图片有异常,线下修正之后需要发布之前进行测试,有些情况下,QA同学有直接在线上环境测试的需求,只是链接本地资源,通常在windows下有一个很好的工具fiddler可以完成这个功能,当然mac下也有其对应的工具Charles,但是工具收费,在不付费的前提下,使用体验很差。
- 线上js资源出了bug,线下修复之后通过测试区不好还原场景,因为只有在线上的数据环境下才能重现bug,但是在线上的代码一般都是混淆过的,调试很不友好(这里不考虑生成soucemap的场景)
- 其它需要使用本地资源替换线上资源的情况
flyover是什么
- flyover是一个简易的本地网络代理工具,基于Puppteer做网络拦截,可以实现对线上压缩代码的调试。
- flyover基于node & puppeteer实现 & 代码开源(当然发布没几天,可能会有很多问题,欢迎大家issue)
如何使用flyover
- npm install -g flyover
- flyover --help具体细节见
https://github.com/JerrZhang/flyover ,欢迎issue 和 star
flyover 实现原理
我们知道所有请求,无论是页面请求还是js 发起的各种请求,最终都是通过浏览器软件发起的,服务器响应后,都是响应给浏览器的,那么整个工程可以细分为如下流程(个人理解):
- 请求浏览器发起请求
- 浏览器接到请求申请,发起请求到服务器
- 服务器处理后响应给浏览器
- 浏览器把响应给上层引擎(比如UI引擎& js引擎等)
puppeteer提供了在第2阶段和第4个阶段的拦截,可以完成浏览器接到请求之后,终端到远程服务器的请求,转而读取本地资源响应给上层引擎;依次来实现对资源的本地化拦截和替换;技术实现也比较简单,只需要在启用拦截后,监听page 对象的request事件进行处理即可,核心代码如下:
//启用请求拦截
this.page.setRequestInterception(true);
//监听请求事件
this.page.on('request', (req) => {
//如果包含在拒绝列表中的文件
let denyFile = this._isInCtrllist(req.url(), ctrlsfiles);
if (denyFile.getIsDenyFile()) {
//直接响应本地文件内容
req.respond({
body: denyFile.getFileContent()
});
} else {
//其它情况请求继续
req.continue();
}
})
简单的几行代码就实现了一个初级的网络拦截工具,是不是很简单实用?
完整代码 https://github.com/JerrZhang/flyover
不足
- 只能使用chrome浏览器来测试,这是由于puppeteer本身的限制决定的
- 还无法支持sourcemap,2.0中会支持添加sourcemap来进行调试