前端应该知道的web调试工具——whistle

whistle 是什么

这里引用一下官方的定义

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

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

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

为什么选择 whistle

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

我经常使用的一些场景如下,后面我们针对一些场景做一些讲解和实战

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

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

官方图片

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

第三点,不像 window 中的 Fidder 需要消耗大量 CPU,也不像 MacCharles 不是免费的(当然也可以破解),它是免费的,开源的,而且一个跨平台 web 调试代理工具

第四点基于 Node 模块和可以通过 Node 模块进行扩展,让我们前端倍感亲切

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

安装

安装这一部分,我这里不打算细讲,具体请看官方文档安装启动

  • 安装 Node,推荐安装最新版的 Node,虽然 whistle 支持 v0.10.0 以上版本的 Node。这一个我相信大家作为一名前端都应该有的环境。这里多插一句,推荐使用 n 管理 node 版本
  • 安装 whistle,如果很慢,请切换源,你懂的。再插一句,推荐使用 nrm 管理你的 npm
npm install -g whistle
// Mac
sudo npm install -g whistle
  • 启动 whistle
    w2 start
    启动之后,我们看到以下,就表示成功了

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

w2 help // 查看帮助,里面很多常用的命令
w2 restart // 重启 whistle
w2 stop // 停止 whistle
w2 run // 调试模式启动whistle(主要用于查看whistle的异常及插件开发)
  • 配置代理,分为全局代理、浏览器代理和移动端代理。这里主要谈谈 mac 端全局代理,chrome 浏览器代理以及 IOS 侧的移动端代理。其他详情可以查看官方文档安装启动。需要注意的是,代理服务器:127.0.0.1 端口号:8899。如果端口被占用,可以通过 -p 来指定新的端口

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

2.浏览器代理。首先先下载 Chrome 代理插件:推荐安装 SwitchyOmega 。考虑到一些朋友在墙内,可以去 这里 下载。然后配置如下:

3.移动端代理。注意,要和当前电脑的 WIFI 是同一个 WIFIIOS 为例

  • 访问配置页面,一切顺利的话,访问 http://127.0.0.1:8899 就可以看到相关的页面
  • 还有一个很重要的步骤:安装根证书,假如不安装根证书的话,就不能抓 HTTPS 的包,安装详情步骤,这一点调试线上问题的时候,可能会遗漏了

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

界面讲解

对于新手来说,我们先熟悉下,whistle 的界面,有个大概的印象
以下是 whistle 的界面,常见的几个选项:
Network——请求列表页面
Rules——操作规则配置页面
Values——存放 KeyValue 的系统
Plugins——插件列表页面

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

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

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

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

# 完全匹配,相当于 Mock 这个接口的返回
https://apinew.juejin.im/recommend_api/v1/article/recommend_all_feed file://{juejinList.json}

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

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

https://apinew.juejin.im/recommend_api/v1/article/recommend_all_feed file://{juejinList.json}
https://apinew.juejin.im/recommend_api/v1/article/recommend_all_feed resCors://{cors.json}

其中 cors.json 内容为

origin: https://juejin.im

查看效果,可以了

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

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

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

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

常用技能

解决跨域问题

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

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 中指定的回调函数的 keycallback,这个很重要,在配置 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 转发配置,我们可以将我们的环境放在不同的规则中,随时切换,而且无缓存,切换时候生效更快

本地代码,调试线上问题

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

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

往 HTML 中插入 脚本 JS

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

配置一个规则:

/https://juejin.im/frontend/i jsAppend://{myJS}

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

往 HTML 中插入 样式

cssAppendcontent-typehtmlcss 的响应内容后面追加数据,如果是 html,则会自动加上 style 标签在追加到响应内容,如果是css,则会自动追加到文本后面

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

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

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

/https://juejin.im/frontend/i cssAppend://{myCSS}

暗黑版掘金

源码中也有了相关的 CSS 样式

以上插入 HTMLCSS 的动图如下

修改 cookie

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

/apinew.juejin.im/interact_api/i reqCookies://{reqcookie}
/apinew.juejin.im/interact_api/i resCookies://{resCookies.json}

reqcookie 内容如下:

name: 'Gopal'
like: '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 功能如下:

https://juejin.im/frontend log://{test.js}

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

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

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

查看移动端页面的 DOM 样式

移动端的 DOM 样式查看和调试对于我们来讲也是一个比较头疼的事情,whistle 就能够做到轻松查看调试移动端的 DOM 样式

https://juejin.im/frontend weinre://test

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

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

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

安装:

npm i -g whistle.inspect

安装成功后,可以在 Plugins 页面中看到

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

配置规则:

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

插件开发

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

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

whistle 实现原理图

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

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

结束语

whistle 作为一个强大的工具,我给大家介绍的只是其中一部分知识,但我坚信其中能够解决大家 80% 的问题了,更多的使用技巧,大家可以看官方文档,去探索吧

参考文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342