高效率代理工具 Whistle 指南

5,195 阅读6分钟

工欲善其事,必先利其器。

工作以来主要从事移动端页面开发,移动端页面开发经常需要通过代理进行真机开发调试,期间使用过 FiddlerSwitchHostsCharlesWhistle 等代理工具,发现 whistle 使用起来效率最高;基于文本的配置方式比起 charles 基于 GUI 配置方式更为简单方便,而且基于 whistle 的插件扩展能力,可以实现更多定制功能,提升开发效率,改善开发体验,非常适合开发同学。

🏆 介绍

whistle 是基于 Node 实现的开源「跨平台 web 调试代理工具」,主要用于查看、修改 HTTP、HTTPS、Websocket 的请求、响应,也可以作为 HTTP 代理服务器使用;whistle 采用的是类似配置系统 hosts 的方式,一切操作都可以通过配置实现,支持域名、路径、正则表达式、通配符、通配路径等多种匹配方式,且可以通过Node模块扩展功能

# Mac 查看系统 hosts 配置 
$ sudo vi /etc/hosts 

原理

whistle 会启动一个代理服务器,所有请求都先经过 whistle,然后再转发到真实服务器,所以可以在 whistle 拦截到请求的时候,对请求做很多定制化的操作,详细原理请查看 HTTP 代理原理及实现

流程图.jpg

🚀 快速开始

安装

安装 whistle 前需要先安装 Node,为获取更好的性能,推荐安装最新版本的 Node。

# whistle 安装,Mac 或 Linux 的非 root 用户需要在命令行前面加 sudo 
$ npm install -g whistle 

最新版本的 whistle 支持三种等价的命令whistle、w2、wproxy ,本文使用 w2。

# 查看版本 
$ w2 -V 

# 查看帮助信息 
$ w2 help 

如果能正常输出 whistle 的版本信息,就表示安装成功了,后面可通过 help 命令查看帮助信息。

启动

whistle 常用命令如下,更多命令行参数请查看命令行参数

# 启动 
$ w2 start 
 
# 重启 
$ w2 restart 
 
# 停止 
$ w2 stop 

whistle 启动后,可以通过 「whistle 控制台」 配置代理、抓包等,控制台功能介绍请查看界面列表

screenshot-20211110-172117.png

配置代理

PC 代理配置

全局代理

全局代理是直接配置系统代理,配置后所有网络请求都会由 whistle 转发,使用模拟器开发调试时需要使用全局代理。

  • Windows
  • Mac:系统偏好设置 -> 网络 -> 高级 -> 代理 -> 网页代理(HTTP)&安全网页代理(HTTPS)

端口号默认为 8899,如果启动 whistle 时指定了端口号记得填入对应端口号。

image-2-1635770283912.png

浏览器代理

浏览器代理需要安装浏览器插件,浏览器配置代理后浏览器网络请求会进行代理,其他浏览器或者软件的网络不受影响。

移动端代理配置

移动端要配置代理的话,需要保证手机 WIFI 和 PC 是同一网络,下面以 iOS 为例,安卓类似。
稿定设计导出-20211111-205722.jpg 服务器 IP 地址和端口可以在 whistle 控制台点击右上角 Online 查看。

安装证书

代理配置完成后可以到控制台抓包验证是否成功,这时你会发现只能抓取 HTTP 请求,如果需要抓取 HTTPS 请求,需要安装 whistle 证书,安装证书详细步骤请参考 whistle HTTPS。 证书安装完成后,还需要开启 HTTPS、Websocket 拦截功能。开启 HTTPS、Websocket 拦截和安装并信任证书,这两个条件缺一不可。 上述步骤缺一不可,都完成后就可以使用 whistle 进行代理开发调试了。

🛠️ 功能

whistle 提供基本上覆盖抓包调试工具可以做的所有功能,下图总结了 whistle 常用功能,完整功能请查看协议列表image.png

配置

whistle 的所有操作都可以通过如下配置实现,配置方式扩展于系统 hosts 配置方式(ip domain或组合方式ip domain1 domain2 domainN),具有更丰富的匹配模式及更灵活的配置方式。whistle 的匹配顺序是从左到右,这与传统 hosts 从右到左的配置方式不同,但为了兼容传统 hosts 配置方式,whistle 多数情况下位置可以调换,即:pattern operatorURI和operatorURI pattern等价。

为了阅读方便,建议配置从左到右书写,pattern operatorURI 不要随意调换位置。

pattern operatorURI 
  1. pattern 为匹配请求 URL 的表达式,可以为域名、路径、正则以及通配符等多种匹配方式,具体内容请查看匹配模式
 # 域名匹配 
 www.example.com 
 
 # 路径匹配,支持带协议、端口 
 www.example.com/test 
 
 # 正则匹配 
 /^https?://www\.example\.com\/test/(.*)/ referer://http://www.test.com/$1 
 
 # 通配符匹配 
 ^www.example.com/test/*** referer://http://www.test.com/$1 

通配符: 域名、路径匹配不能满足一些复杂的情况,虽然正则匹配可以解决所有匹配问题,但门槛还是有点高,且涉及转义及设置匹配的起始位置等,对一些常用匹配 whistle 提供了一些更简单的配置方式,包含通配符匹配、通配域名匹配、通配路径匹配;通配符匹配模式必须以 ^ 开头(如果需要限制结束位置可以用 )为通配符,支持通过),* 为通配符,支持通过 0...9 获取通配符匹配的字符串,其中 $0 表示整个请求 URL,更多用法请查看匹配模式 - 通配符匹配

  1. operatorURI 为对应的操作,由操作协议 + 操作值组成。
operatorURI = operatorProtocol://operatorValue 
  • operatorProtocol(操作协议),对应某类操作,如:
# 本地替换,file 协议
pattern file://opValue
  • operatorValue(操作值),对应具体操作的参数值,如:
# 本地替换,file 协议 
pattern file:///User/test/dirOrFile # 或 pattern /User/test/dirOrFile 
  1. patternoperatorURI 支持组合模式,具体请查看配置方式
# 传统组合方式 
# 一个 pattern 对应多个操作 
pattern operatorURI1 operatorURI2 operatorURIN 
 
# 如果 pattern 部分为路径或域名,且 operator URI为域名或路径 
# 这种情况下也支持一个操作对应多个 pattern 
operatorURI pattern1 pattern2 patternN 

常用功能

host 转发

本地开发时把请求转发到本地端口,可以用来去掉开发时 URL 中的端口号,转发后可以直接使用线上地址访问本地页面,能够解决本地开发时相对路径跳转以及接口跨域等问题,更多用法请查看 host 协议

# 本地端口映射 
# 线上地址:https://www.example.com/test 
# 开发地址:https://localhost:4000/ 
www.example.com 127.0.0.1:4000 
 
# 页面 a 会转发到页面 b 
# 可用于调试内嵌 APP 页面,APP 内有一个入口链接 a,而调试的目标页面是 b 
www.example.com/a.html www.example.com/b.html 

修改请求头

修改请求头使用 reqHeaders 协议,可以用来配置后端接口泳道,大括号里面的值为操作值

www.example.com/api/xxx reqHeaders://{key}

延迟响应

设置延迟响应时间(单位:毫秒)使用 resDelay 协议,可以用来模拟接口返回较慢。

# 模拟接口 5s 后返回 
www.example.com/api/xxx resDelay://5000 

修改响应状态码

修改响应状态码使用 statusCode 或者 replaceStatus 协议,可以用来模拟接口返回出错。 replaceStatus 是请求响应后再修改状态码,而 statusCode 请求不会发出去,设置完状态码直接返回。

# 模拟接口返回 500 错误 
www.example.com/api/xxx statusCode://500 

替换响应内容

把指定内容替换为响应内容( 304 等响应没有内容无法替换)使用 resBody 协议,可以用来 mock 数据。

# 指定内容替换为本地文件 
www.example.com/xxx resBody://filepath 
 
# 指定内容替换为 whistle 操作值 
www.example.com/xxx resBody://{key} 

追加响应内容

把指定内容追加到响应内容后面( 304 等响应没有内容无法追加)使用 resAppend 协议,追加到响应内容前面使用 resPrepend 协议,可以用来注入一些自定义脚本等,比如 vConsole 等。

# 指定内容追加到响应内容后面 
www.example.com/xxx resAppend://{key} 
 
# 指定内容追加到响应内容前面 
www.example.com/xxx resPrepend://{key} 

跨域

修改响应的 cors 使用 resCors 协议,可以用来解决跨域问题。

# `*` 表示设置 access-control-allow-origin: * 
www.example.com resCors://* 
 
# `enable` 表示设置 access-control-allow-origin: http://originHost 
# 及 access-control-allow-credentials: true 
www.example.com resCors://enable 

移动端调试

移动端调试主要通过注入 vConsole、使用 weinre 远程查看、修改页面的 DOM 结构及样式,以及使用 log 打印日志 debug,具体用法请查看利用whistle调试移动端页面

  • 注入 vConsole
www.example.com jsAppend://{vConsole.js} 
  • weinre
# xxx 为对应的 weinre id,主要用于页面分类,默认为 anonymous 
www.example.com weinre://xxx 
  • 打印日志
# xxx 为页面分类,为了方便同时调试不同的网页 
www.example.com log://xxx 

设置抓包样式

设置抓包列表行样式使用 style 协议,可以用来高亮指定请求,方便查看。

# color: 字体颜色,同 css color 属性,由于 `#` 为 whistle 注释符号,可以用 `@` 代替 
# fontStyle: 字体样式,可以设置为 normal、italic、oblique 等 
# bgColor: 对应列表行的背景颜色,具体设置同 color 
www.example.com/api/xxx style://color=@fff&fontStyle=italic&bgColor=red 

过滤配置

过滤配置使用 excludeFilterincludeFilter 协议,excludeFilter 表示排除匹配的请求,includeFilter 只保留匹配的请求。

# host 转发过滤后端接口请求 
www.example.com 127.0.0.1:4000 excludeFilter://*/aweme/ 

清除缓存

Chrome 浏览器可以通过打开开发者工具,并勾选 Network 菜单里面的Disable cache实现禁用当前页面的缓存,移动端不支持这种方式,需要借助代理工具实现,用 whistle 清除页面静态资源缓存的方式主要为下面两种:

  1. 禁用页面 304 及缓存头:disable://cache
  2. 通过正则替换给页面里面长缓存静态资源链接添加随机参数:resReplace
# 禁用请求的缓存,只要经过代理且匹配到的请求都不会使用缓存,包括强缓存和协商缓存 
www.example.com disable://cache 
 
# 给页面中的 js、css 请求地址添加时间戳参数
# ``` assetsURL 
# /\.(js|css)(['"])/g: .$1?time=${now}$2 
# ```
www.example.com/index.html disable://cache resReplace://`{assetsURL}` 

🔌 插件

为了满足一些特定业务场景的需要,whistle 提供了插件扩展能力,通过插件可以新增 whistle 的协议实现更复杂的操作、也可以用来存储或监控指定请求、集成业务本地开发调试环境等,基本上可以做任何你想做的事情。每个 whistle 插件就是一个普通的 npm 包,所以开发、发布及安装 whistle 插件都很简单;whistle的插件是一个独立运行的进程,插件运行不会影响到 whistle 主进程的稳定性。更多插件请查看 whistle-plugins

常用插件

inspect

移动端页面开发时经常需要在页面上注入 vConsole 进行调试,一般做法是在 html 中引入 vConsole,开发环境打开,正式环境注释或者删除,容易不小心发布上线;还有个问题就是线上页面没法使用 vConsole 调试,使用 whistle.inspect 插件可以在不侵入页面代码的情况下注入 vConsole,线上页面也能注入。

# 安装 inspect 插件 
$ w2 i whistle.inspect 

在需要注入的页面配置:

www.example.com whistle.inspect://vConsole 

🌰 项目实践

推荐使用全局代理,不会影响其他软件网络,全局代理方便使用「模拟器」进行移动端开发。

注意重启 Mac 后需要先启动 whistle 后才能访问网络。

  • PC 端使用全局代理和浏览器代理都可以;
  • 移动端推荐使用 whistle 全局代理 + 模拟器开发,效率非常高。

规则配置文件

初始化项目时在根目录下增加 .whistle.js 规则配置文件,其他同学在项目根目录下运行 w2 add 或者 w2 use 就可以添加这个配置;也可以通过类似 charles 导入、导出配置的功能。

// .whistle.js 
const pkg = require('./package.json'); 
 
exports.name = `[${pkg.name}]本地环境配置`; 
exports.rules = `www.example.com 127.0.0.1:3000`; // 多行规则用 \n 分隔 
# 添加规则配置 
$ w2 add 

参考文档