你需要知道的前端调试利器——whistle

whistle 是什么

引用 官方的定义[1]

whistle,拼音[wēisǒu])基于 Node 实现的跨平台 web 调试代理工具,类似的工具有 Windows 平台上的 Fiddler,主要用于查看、修改 HTTP、HTTPS、Websocket 的请求、响应,也可以作为 HTTP 代理服务器使用,不同于 Fiddler 通过断点修改请求响应的方式,whistle 采用的是类似配置系统 hosts 的方式,一切操作都可以通过配置实现,支持域名、路径、正则表达式、通配符、通配路径等多种匹配方式,且可以通过 Node 模块扩展功能

总的来说,whistle 有如下几个特性

基于 Node 实现,跨平台 web 调试代理工具,window,Linux,Mac 都可以使用用于查看、修改 HTTP、HTTPS、Websocket 的请求、响应,也可以作为 HTTP 代理服务器使用whistle 采用的是类似配置系统 hosts 的方式,一切操作都可以通过配置实现可以通过 Node 模块扩展功能

为什么选择 whistle

第一,whistle 是一个 web 调试代理工具,它的功能十分强大。作为一名前端,我们需要经常跟协议中的应用层打交道,Mock 数据、跨域问题、cookie 的修改、移动端调试等等,都是我们必备的技能,而 whistle 就能解决其中 90% 的问题

个人经常使用的一些场景如下:

绑定 Host替换请求(Mock 数据)使用 Weinre 或者 vConsole 调试移动端页面修改 cookie往 HTML 中插入样式往 HTML 中插入脚本 ...

以下为官方的一张图,大家可以感受一下

第二,除了功能十分强大,使用也十分便捷,只需要简单的命令就能打开网页进行抓包等操作

第三,不像 window 中的 Fidder 需要消耗大量 CPU,也不像 Mac 中 Charles 不是免费的,它是免费的,开源的,而且一个跨平台 web 调试代理工具

第四,基于 Node 模块实现。可以通过 Node 模块进行扩展

以上,还没说服你的话,希望接下来的实战能够让你感受它的强大

安装

安装 Node,推荐安装最新版的 Node,虽然 whistle 支持 v0.10.0 以上版本的 Node。这一个我相信大家作为一名前端都应该有的环境。这里多插一句,推荐使用 n 管理 node 版本

用以下命令安装 whistle,如果很慢,请切换源进行安装。再插一句,推荐使用 nrm 管理你的 npm 源

npm install -g whistle// Macsudo npm install -g whistle启动 whistle。通过命令 w2 start 即可启动。启动之后,我们看到以下提示,就表示安装成功了

这里还需要留意其他几个经常使用的命令

w2 help // 查看帮助,里面很多常用的命令w2 restart // 重启 whistlew2 stop // 停止 whistlew2 run // 调试模式启动whistle(主要用于查看whistle的异常及插件开发)

配置代理,分为全局代理、浏览器代理和移动端代理。这里主要谈谈 mac 端全局代理,chrome 浏览器代理以及 IOS 侧的移动端代理。其他详情可以查看官方文档 安装启动[2]。需要注意的是,代理服务器:127.0.0.1 端口号:8899。如果端口被占用,可以通过 -p 来指定新的端口

1.全局代理(mac):System Preferences > Network > Advanced >Proxies > HTTP or HTTPS

2.浏览器代理。首先先下载 Chrome 代理插件:推荐安装 SwitchyOmega[3] 。考虑到一些朋友无法很好的下载安装,可以去 这里[4] 下载。然后配置如下:

3.移动端代理。注意,要和当前电脑的 WIFI 是同一个 WIFI。以 IOS 为例(安卓同理)

访问配置页面,一切顺利的话,访问 :8899[5] 就可以看到相关的页面

还有一个很重要的步骤:安装根证书,假如不安装根证书的话,就不能抓  HTTPS 的包,详情请看 安装详情步骤[6]

以上就是我们的准备工作了,可能还是一些同学还是会遇到一些问题,可以去官方 issue[7] 看看有没有相关的解决方法,也可以留言评论,我们一起看看

界面讲解

对于新手来说,我们先熟悉下 whistle 的界面,有个大概的印象

以下是 whistle 的界面,常见的几个选项:

Network——请求列表页面

Rules——操作规则配置页面

Values——存放 KeyValue 的系统

Plugins——插件列表页面

快速上手——基础使用【mock 数据以及解决跨域】

whistle 使用的是类似代理的方式,Rules 版面下默认有一个 default 的分组,我们可以创建、重命名、删除一个分组,可以根据以下示例快速建立一个分组,如动图所示:

接下来,我们就可以在右侧建立一些规则了。我们来拿掘金做个演示吧,掘金推荐首页获取列表数据的接口为 ,以下是目前的页面,注意,该接口的响应头设置了  access-control-allow-origin:

我们根据这个接口设置一条规则,以下规则表示完全匹配该接口,返回指定的 juejinList.json 数据,相当于 Mock 这个接口的返回

# 完全匹配,相当于 Mock 这个接口的返回 file://{juejinList.json}

查看效果,报错了,看看报错,跨域问题,线上的之所以没有报错,原因在于,线上的接口的响应头设置了  access-control-allow-origin: ,所以我们还应该 Access-Control-Allow-Origin 请求头

怎么办,就没有方法了么?当然不是,这个时候只需要多配置另外一条规则,总的规则如下:

file://{juejinList.json} resCors://{cors.json}

其中 cors.json 内容为

origin:

查看效果,可以看到访问掘金推荐首页,返回了我们代理的数据了

我们来看下 Network 版面,选中我们代理了的接口,可以看到已经走了我们所配置的规则了

上面我们是通过精确匹配匹配到了掘金的获取列表接口,写起来会很长,其实我们可以通过域名、路径、正则、精确匹配、通配符匹配等方式去匹配的,比如如下的规则也是可以的

/v1/article/recommend_all_feed/i file://{juejinList.json}/v1/article/recommend_all_feed/i resCors://{cors.json}

基础的使用就是这么简单,这里我们就解决了 Mock 数据以及跨域的问题。当然,这只是 whistle 其中一个小功能,接下来才是重头戏

常用技能

解决跨域问题

可以通过 reqCors 修改请求的 CORS[8]。也可以通过 resCors 修改返回的 CORS[9] 。从而达到解决跨域的效果。上面的例子已经演示过,这里不再重复

Mock 数据

通过上面提到的 file:// 协议,我们就可以 Mock 数据,当然你如果不想使用 Values 中的值,也可以使用本地的文件,类似如下的配置:

# 注意是绝对路径/v1/article/recommend_all_feed/i file:///Users/gpingfeng/Documents/Personal/Test/juejinList.json

模拟 JSONP 返回

如果是 JSONP,我们要怎么 Mock 呢?这里我们用到了 tpl 协议,tpl 协议基本功能跟 file 协议一样可以做本地替换,但 tpl 内置了一个简单的模板引擎,可以把文件内容里面 {name} 替换请求参数对应的字段(如果不存在对应的自动则不会进行替换),一般可用于 mock jsonp 的请求

这里我们拿京东首页的一个获取轮播图的接口作为演示。我们可以看到 URL 中指定的回调函数的 key 为 callback,这个很重要,在配置 Values 的时候会用到

我们配置规则,修改返回为了路飞的图片

# 匹配到京东首页获取轮播图的接口,修改接口返回/floor.jd.com/recommend-v20/focus_monetize/i tpl://{jsonp.json}

其中 jsonp.json 中的格式为

// callback 是根据上面 JSONP 请求中发送出去的回调函数决定的{callback}({// 这里是返回的 JSON,这里我就是替换了返回的图片而已})

看结果,生效了

绑定 Host

一提到绑定 Host,我们会想起使用 Switch Host 切换,但使用 whistle 可以更加方便和强大,不仅支持传统的 Host配置,还支持子路径和端口的 Host 转发配置,我们可以将我们的环境放在不同的规则中,随时切换,而且无缓存,切换时候生效更快

本地代码,调试线上问题

有时候,我们遇到线上的问题,却因为数据问题,没有办法在本地复现。一般我们项目 api 的 url 都会设计带上后缀,利用这个,我们可以配置如下的规则,轻松调试线上的问题

# 接口走线上^example.com/api/*** https://example.com/$1# 访问走本地^example.com/*** :8120/$1

往 HTML 中插入 脚本 JS

jsAppend 协议往 content-type 为 html 或 js 的响应内容后面追加数据,如果是 html,则会自动加上 script 标签在追加到响应内容,如果是 js,则会自动追加到js文本后面

配置一个规则:

# 往掘金页面中注入脚本//frontend/i jsAppend://{myJS}

查看效果:

查看源码,可以看到已经自动加上 script 标签在追加到响应内容

往 HTML 中插入 样式

cssAppend 往 content-type 为 html 或 css 的响应内容后面追加数据,如果是 html,则会自动加上 style 标签在追加到响应内容,如果是css,则会自动追加到文本后面

我们给掘金网页版加上暗黑模式吧,以下是 myCSS

html {    filter: invert(1) hue-rotate(180deg);}

我们配置规则,插入到掘金中

# 往掘金中插入 CSS//frontend/i cssAppend://{myCSS}

暗黑版掘金

查看网页源码,已经有了相关的 CSS 样式

修改 cookie

开发中,我们很多时候,需要设置请求头或者响应头的 cookie,这个时候,我们就需要用到 reqCookies 和 resCookies。它们的功能分别是修改请求头的 Cookie 和 修改响应头的 Set-Cookie

# 修改请求头的 `Cookie`/apinew.juejin.im/interact_api/i reqCookies://{reqcookie}# 修改响应头的 `Set-Cookie`/apinew.juejin.im/interact_api/i resCookies://{resCookies.json}

reqcookie 内容如下:

name: Gopallike: FE

效果如下:

resCookies.json 的内容如下

{    "name": "Feng",    "age": "26",    "happy": {        "value": "FE",        "maxAge": 60,        "httpOnly": true,        "path": "/",        "secure": true    }}

效果如下:

真正的杀手锏——移动端调试

相比于在 PC 端,在移动端调试网页,主要会遇到以下两个问题:

没有 Console,无法查看页面的 js 错误及通过 console.xxx 输出的调试日志无法查看、修改页面的 DOM 结构及样式

虽然很多移动端页面,我们可以在 Chrome 的模拟器中进行调试,但不是所有的移动端页面都可以在 PC 端调试和复现问题。往往在 APP 中嵌入的页面,在不同的机器中会遇到兼容性问题,需要在真机中才能看到效果或者复现问题,这个时候就需要我们的 whistle 登场了

移动端捕获页面错误和 log

移动端,我们查看报错信息也是比较麻烦的,为此,whistle 提供了 log 功能如下:

/frontend log://{test.js}

test.js 主要是模拟脚本报错,内容如下:

console.error({ error: true });console.warn({ error: true, warn: { test: true } });console.log();// 模拟抛出异常console.notAFunction(test);

在 Network —— Tools 下面就可以看到报错等日志了

具体的操作演示动画如下:

查看移动端页面的 DOM 样式

移动端的 DOM 样式查看和调试对于我们来讲也是一个比较头疼的事情。whistle 就能够做到轻松查看调试移动端的 DOM 样式,就跟调试桌面端的浏览器一样,这个是通过 whistle 内置的 weinre 去实现的

配置规则如下,其中 test 只是作为一个标识:

/frontend weinre://test

演示动图以及效果如下:

使用插件——利用whistle注入vConsole

vConsole[10]  是团队开发的轻量、可拓展、针对手机网页的前端开发者调试面板,主要原理是通过在页面注入 js 实现模拟 PC 浏览器的 Console 功能

因为官方没有提供,所以我们这里选择使用插件的方法,顺便介绍下插件的用法(每个插件的用法不同,大家举一反三)

首先,安装插件

# 安装插件npm i -g whistle.inspect

安装成功后,可以在 Plugins 页面中看到我们安装的插件:

安装插件后,只需配置简单的规则即可随意切换 vConsole 和 eruda,这里我们只演示 vConsole

配置规则:

/juejin.im/i whistle.inspect://vConsole

演示动图如下:

插件开发

上面提到了插件的使用,为了满足一些特定业务场景的需要,whistle 也提供了插件扩展能力,通过插件可以新增 whistle 的协议实现更复杂的操作、也可以用来存储或监控指定请求、集成业务本地开发调试环境等等,基本上可以做任何你想做的事情,且开发、发布及安装 whistle 插件也都很简单。

whistle 的插件是一个独立运行的进程,这样是为了确保插件不会影响到 whistle 主进程的稳定性,并通过暴露一些 http server 的方式实现与 whistle 的交互,whistle 会在特定阶段请求特定的 server,具体看下面的原理图:

从上面几个图可以知,whistle 插件会设计以下7种 server,也就是有7种强大的功能

statsServer:统计请求信息的服务resStatsServer:统计响应信息的服务rulesServer:设置请求规则的服务(支持 http/https/websocket 请求)resRulesServer:设置响应规则的服务(支持 http/https/websocket 请求)tunnelRulesServer:设置 tunnel 请求规则的服务server:whistle 会把指定请求转发到该 serveruiServer: whistle 插件的界面,可以通过特定的 url 访问

结束语

whistle 作为一个强大的工具,我给大家介绍的只是其中一部分知识,但我坚信其中能够解决大家 80% 的问题了,希望能够对大家平时工作带来帮助。更多的使用技巧,大家可以查看 官方文档[11]

参考文章

官方文档[12] 利用whistle调试移动端页面[13]whistle--前端调试利器[14]

参考资料

[1]

官方的定义:

[2]

安装启动:

[3]

SwitchyOmega:

[4]

这里:

[5]

:8899: :8899/

[6]

安装详情步骤:

[7]

issue:

[8]

CORS:

[9]

CORS:

[10]

vConsole:

[11]

官方文档:

[12]

官方文档:

[13]

利用whistle调试移动端页面:

[14]

whistle--前端调试利器: /entry/6844903684736827400

交流讨论

欢迎关注「前端试炼」,平时会分享一些实用或者有意思的东西,发现代码之美。专注深度和最佳实践,希望打造一个高质量的。

二维码个人

添加个人回复「加群」,拉你进交流面试群。

如果你不想加群,只是想加我也是可以的。

如果觉得这篇文章还不错,来个【分享、点赞、在看】三连吧,让更多的人也看到~