一文搞定前端代理骚操作!再也不怕线上bug啦!
徐帅武,微医云服务团队前端工程师。一个热衷于周末“搞事情”的前端程序猿
前言
为什么我们需要一个代理工具?一个灵活好用的代理工具对开发的作用有多大?
一个顺手的代理工具,可以让我们随心所欲的掌控我们的开发环境,当前环境前置服务挂了还要等重启?不!直接切一个可用环境接着我的开发。验证页面不同数据状态的流程还要造数据?不!直接代理修改数据走流程,省劲。特定机型线上问题抓耳挠腮不知如何定位?代理连上查看元素、远程 log 轻松定位问题所在......
使用代理不说能解决所有问题,但是至少可以在解决问题的流程上帮我们省大半的时间,而不是碰到环境问题就在那儿等重启
Whistle 介绍
关于 Whistle 下面引用官方的
Whistle(读音[ˈwɪsəl],拼音[wēisǒu])基于 Node 实现的跨平台 web 调试代理工具,类似的工具有 Windows 平台上的 Fiddler,主要用于查看、修改 HTTP、HTTPS、Websocket 的请求、响应,也可以作为 HTTP 代理服务器使用,不同于 Fiddler 通过断点修改请求响应的方式,Whistle 采用的是类似配置系统 hosts 的方式,一切操作都可以通过配置实现,支持域名、路径、正则表达式、通配符、通配路径等多种匹配方式,且可以通过 Node 模块扩展功能
与 Charles 对比
想必大部分人刚开始接触抓包代理的时候用的都是 Charles 和 Fiddler 这两个老牌抓包代理工具之一,笔者当初就是 Charles 入的门。但是后面了解到 Whistle 之后就毅然选择投入了它的怀抱。下面说一下笔者认为 Whistle 的几大优势。
开源免费,相比 Charles 的收费,开源的 Whistle 使用起来当然是更加的没有负担。 易于安装,Whistle 基于 Node 实现,安装就是全局安装 npm 包,对于前端来说当然是更加的友好。 配置集中灵活,Whistle 的各种功能都使用配置文件的方式集中管理,查看和修改都更加友好且易于分享。 自由可编程,当内置功能都不能满足需求时,还可以使用 Npm 包的方式开发插件对于 JS 开发者来说更加的友好易用。
如何使用
安装和使用
因为是 npm 包,所以安装只需要一句话(Mac 或 Linux 的非 root 用户需要在命令行前面加 sudo,如:sudo npm install -g whistle
)
# 安装
npm install -g whistle
# 启动
w2 start
# 重启
w2 restart
# 停止
w2 stop
访问主界面
一般情况下直接访问http://localhost:8899/#network
这个地址即可,不使用默认端口的话,改为启动的端口号访问即可。界面如下:
配置代理
配置信息
代理服务器:127.0.0.1 (如果部署在远程服务器或虚拟机上,改成对应服务器或虚拟机的 ip 即可)
默认端口:8899 (如果端口被占用,可以在启动时通过 -p 来指定新的端口,更多信息可以通过执行命令行 w2 help (v0.7.0 及以上版本也可以使用 w2 help) 查看)
由于 Whistle 不能自动设置系统代理,所以需要代理的内容需要手动配置
系统代理
这个不常用,各个系统设置系统代理方式不同,可自行查找设置方式
浏览器代理(Chrome 为例)
虽然 Chrome 也可以设置代理,但是更推荐使用SwitchyOmega
插件进行代理的管理,可以同时配置梯子的代理规则,不至于开了代理就不能访问 Google 了
移动端代理
移动端代理需要两个设备在同一 WiFi 下(网络互通),在设置中配置当前 Wi-Fi 的代理,以 iOS 为例:代理服务器为启动 Whistles 设备的 IP
https 证书
会配置或没有 https 需求的可跳过这一段。
https 默认时不能查看其内容的我们需要安装自定义的根证书来进行 https 请求的查看,这部分内容没有什么特别的下面就直接把文档上的内容复制过来了。
下载根证书,开启捕获 HTTPS 请求:
安装根证书
证书按下面步骤安装后,如果还出现安全提醒,这个主要原因是之前你访问过该页面,导致长连接已建立,可以等段时间再访问、或重新打开浏览器,或重启下 Whistle:w2 restart
如上图下载完根证书后点击 rootCA.crt 文件,弹出根证书安装对话框。
Windows:
Installing a root certificate on Windows
下载证书后,双击证书,根据指引安装证书。证书安装过程,要确保证书存储到受信任的根证书颁发机构下。
Mac:
Mac 安装证书后,需要手动信任证书,步骤如下:
打开证书管理界面,找到带有 whistle 的字样的证书,如果有多个又不确定最新安装的是哪个,可以全部删除后重新安装
双击证书后,点击 Trust 左边展开选项,红色部分选择 Always Trust (总是信任),点击左上角关闭当前界面会要求输入密码;输入密码后可 以看到证书上面红色的图标 x 不见了,到这一步说明完成证书安装。
Firefox:
菜单 > 首选项 > 高级 > 证书 > 证书机构 > 导入 -> 选中所有 checkbox -> 确定
iOS
手机设置代理后,Safari 地址栏输入 rootca.pro,按提示安装证书(或者通过 whistle 控制台的二维码扫码安装,iOS 安装根证书需要到连接远程服务器进行验证,需要暂时把 Https 拦截功能关掉) iOS 10.3 之后需要手动信任自定义根证书,设置路径:Settings > General > About > Certificate Trust Testings 具体可以看这里
Android
whistle 控制台二维码扫码安装,或者浏览器地址栏 rootca.pro 按提示安装 部分浏览器不会自动识别 ca 证书,可以通过 Android Chrome 来完成安装 android 6.0 之后的一些 app 在成功安装证书后仍然无法对 https 连接进行手抓包,有可能是该 app 没有添加信任用户自定义证书的权限。请确认该 app 是否有如下配置:
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
trust-anchors>
base-config>
这主要是因为 android 6.0 之后的版本默认配置发生了变化,更多请看 Android 开发文档。
开启拦截 HTTPS
图中的打开的对话框有个 checkbox:
1.Capture HTTPS CONNECTs:开启 Https 拦截功能,只有勾上这个 checkbox 及装好根证书,Whistle 才能看到 HTTPS、Websocket 的请求
自定义请求证书或根证书
whistle 会自动生成根证书,并根据根证书对每个请求动态生成 https 证书,如果需要用自定义的证书,甚至根证书,可以有两种方式(只支持 .crt 格式的证书):
把普通证书对 (如:test.crt 和 test.key、test2.crt 和 test2.key 等等) 或根证书 (名字必须为 root.crt 和 root.key),放在系统的某个目录,如 /data/ssl,并在启动时添加启动参数 w2 start -z /data/ssl ,whistle 会自动加里面的证书 (v1.14.8 及以上版本支持) 把上述证书或根证书放在固定目录 ~/.WhistleAppData/custom_certs/里面,whistle 会自动加里面的证书
优先级 -z dir > ~/.WhistleAppData/ > 内置证书
匹配规则
Whistle 的匹配规则非常的多,这里介绍几种常用的匹配模式基本可以覆盖 90%的使用场景。详细规则可以查看【匹配规则】
注: 默认匹配规则都是下面这种形式:pattern operatorURI
,匹配规则在左,操作规则在右。
域名匹配
# 匹配域名 www.test.com 下的所有请求,包括 http、https、ws、wss,tunnel
www.test.com operatorURI
# 匹配域名 www.test.com 下的所有 http 请求
http://www.test.com operatorURI
# 匹配域名 www.test.com 下的所有 https 请求
https://www.test.com operatorURI
# 上述匹配也可以限定域名的端口号
www.test.com:8888 operatorURI # 8888 端口
www.test.com/ operatorURI # http 为 80 端口,其它 443 端口
路径匹配
# 限定请求协议,只能匹配 http 请求
http://www.test.com/xxx operatorURI
http://www.test.com:8080/xxx operatorURI
# 匹配指定路径下的所有请求
www.test.com/xxx operatorURI
www.test.com:8080/xxx operatorURI
通配符匹配
通配符匹配以 ^ 开头,* 为通配符,可以通过 9 匹配通配符匹配的分组,$0 表示整个 URL。
# 通配符匹配必须以 ^ 开头
# 访问 wy.guahao.com/abc/xyz/1.js 就会被映射到 /path/to/xyz/1.js
^wy.guahao.com/abc/*** /path/to/$1
# 也可以用 $ 限制结尾
# 只转发 index.js 结尾的 url
^wy.guahao.com/abc/***index.js$ /path/to/$1
* 表示匹配到一个 / 就停下,而 *** 表示匹配多个
域名通配符
在域名中使用 * 不需要用 ^ 开头,例如我们用*.com operatorURI
时就是匹配 guahao.com
等,但是不匹配 www.guahao.com
。而想要对所有子域名生效,可以用***.com operatorURI
这样可以匹配 wx.wy.guahao.com
这样的域名
正则匹配
对于非常灵活的匹配规则,可以使用正则匹配。
# 匹配所有请求
/./ operatorURI
# 匹配 url 里面包含多个关键字的请求
/keyword/ operatorURI
# 通过正则匹配,同样的 $1~$9 捕获分组,$0 表示整个 URL
/(\d+).html/ operatorURI
常用功能
绑定 Host
和 Host 文件写法相同,走代理的时候不会再查询本机的 Host 文件,修改这个 Host 配置没有缓存,立即生效
127.0.0.1 wy.guahao.com
替换请求
调试一些有域名校验难以在本地查找的问题时(比如微信授权,微信 SDK 调用),可以将线上的页面代理到本地开发环境来进行问题排查。
针对一些非 Webpack 编译的资源可以将线上资源替换,达到直接调试线上的效果。前后端不分离的项目,本地环境难以配置时,可以在测试环境调试本地的 JS、CSS 文件。
# 本地替换线上
127.0.0.1 wya.guahao.com
https://wy.guahao.com http://wya.guahao.com:8080
# 代理替换资源
^http://test.guahao-test.com/front/hps-h5-static/css/h5.min.css*** http://127.0.0.1:9091/front/hps-h5-static/css/h5.css
^http://test.guahao-test.com/front/hps-h5-static/js/h5.js*** http://127.0.0.1:9091/front/hps-h5-static/js/h5.js
替换返回内容
文本类请求 append 内容、替换返回内容
# 说明:会把内容 append 到请求后面
http://guahao.com/style.css resAppend://{myAppend.css}
# 说明:完全替换请求内容
http://guahao.com/style.css resBody://{myResBody.css}
注入 JS 脚本
线上项目我们一般不会启用 vConsole,Eruda 之类的调试工具。出现问题时难以查看报错与其他信息。这时可以使用代理将 vConsole,Eruda 注入到页面中来查看问题。
# htmlAppend 操作即为在 html 部分最后注入 debugger 变量,变量内容在“Value”面板进行设置
https://wy.guahao.com/ htmlAppend://{debugger}
debugger 变量的内容:
<script crossorigin="anonymous" integrity="sha384-ltIfi6+efoMR4xY0cwhn9a243JE/09cby6RJioKuqFKzs4un/eTmCLbAGaVM8xsJ" src="https://lib.baomitu.com/eruda/2.2.1/eruda.js">script>
<script>eruda.init();script>
远程 Console.xxx 输出
移动端调试的时候的痛点就是不能查看 log,及时我们用了上面的方法向页面注入 Eruda 之类的调试工具,也免不了两个设备来回切换的查看内容。Whistle 内部实现了类似浏览器的 Console 的远程 Log 平台,使用对应的规则就可以在 PC 端进行其他设备上 log 的查看
# wy.guahao.com 域名的网站远程打印 log
# wy.guahao.com log://
# 远程打印 log 同时注入脚本
wy.guahao.com log://{injection-log}
# --------- Value 部分 ------------
# injection-log 内容
console.log('-----------------start-------------------')
console.log('远程 log')
console.log('查看某个变量', window)
console.log('-----------------end---------------------')
集成 weinre 远程调试
Weinre 是 Apache 基础工程之一,是 WEb INspector REmote 的缩写。正如其名,它是和 Firebug 或浏览器调试工具类似,但是能够在远程运行调试 web 页面。所以如果你使用过火狐开发者工具或 Chrome 的调试工具,那么上手 Weinre 就会非常容易,非常自然。
但是使用 Weinre 的配置十分繁琐,Whistle 可以自动帮我们在页面注入 Weinre 的启动脚本,使我们使用 Weinre 变成了一句话的事情。
# 集成 weinre 的功能, key 为任意的字符串,主要用于区分页面
wy.guahao.com weinre://[key]
小结
上面就是开发过程中笔者常用的几个功能,Whistle 的功能远不止此。有兴趣的可以去 Whistle 文档查看详细内容,下面是它协议列表的一部分,可以看出功能非常的丰富。而且支持插件的编写,有自定义需求时还可以自己编写插件来实现所需的功能。
最后
如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:
点个「在看」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)
欢迎加我微信「qianyu443033099」拉你进技术群,长期交流学习...
关注公众号「前端下午茶」,持续为你推送精选好文,也可以加我为好友,随时聊骚。