阅读 5118

一文搞定前端代理骚操作!再也不怕线上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
复制代码

通配符匹配

通配符匹配以 ^ 开头,* 为通配符,可以通过 1 1~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 文档查看详细内容,下面是它协议列表的一部分,可以看出功能非常的丰富。而且支持插件的编写,有自定义需求时还可以自己编写插件来实现所需的功能。