介绍

whistle 是一款用 Node 实现的跨平台的 Web 调试代理工具,支持查看修改 http(s)、Websocket 连接的请求和响应内容。简而言之就是 Node 版的 Fiddler、Charles,不过这个工具能远比后两者更加适合 Web 开发者、使用更简单、功能也更加实用,完全可以代替 Fiddler、Charles。

相关工具与安装

whistle 安装与启动

$ npm install -g whistle$ w2 start  // 启动
$ w2 stop   // 停止
$ w2 restart // 重启
$ w2 help    // 其他命令可查看帮助
复制代码

启动成功之后,便可以在http://127.0.0.1:8899查看whistle的web界面。

SwitchyOmega 安装

这是一个 chrome 插件,用来配置浏览器代理,常用来配合 whistle 使用。(如果要把 whistle 作为全局代理使用,可以参考这里)

下载并且安装插件之后,在插件配置页配置代理服务:

如果本机有使用其他代理,比如翻墙,SwitchyOmega 允许切换到“系统代理”。

使用

常用功能

在 web 界面,主要的功能有 network、rules、values、plugins。

network 中可以查看被代理的请求,其中有一系列charles等工具的功能。

rules 用来配置代理规则,是下面主要介绍的功能。

values 配置要常用的键值对。

plugins 中是可以使用的插件,plugins的插件可以看这里。

下面主要来看下 rules 的使用。

rules

替换hosts

在 whistle 添加配置相当于在浏览器层面添加hosts,会优先于系统hosts。

127.0.0.1 www.test.com
www.test.com 127.0.0.1  # 和上面一行同义
www.test.com 127.0.0.1:8080
# www.test.com 127.0.0.1  # 这行被注释掉,不生效
http://www.test.com 127.0.0.1:8080 # 只会代理http请求,https会被忽略
127.0.0.1 www.test.com www.test1.com www.test2.com
复制代码

whistle 默认的配置方式是 pattern 在左,替代请求的 URL 在右。而传统hosts 配置是 URL 在左 pattern 在右。

127.0.0.1 www.test.com   # 传统
www.test.com 127.0.0.1  # whistle默认
复制代码

whistle会尽量兼容上面两种格式,如果出现不能够兼容的情况,比如:

http://www.baidu.com http://www.sina.com
复制代码

这样的话会按照 whistle 默认格式来对待。

本地替换

尤其在本地开发完成,或者线上功能优化的时候,你可能需要把请求线上资源的请求替换到本地。

www.test.com/resource/js file://D:/projects/hello/resource
复制代码

html中插入JS

# 如果是html,则会自动加上 script 标签再替换响应内容,如果是js,则会自动替换整个js文件
www.ifeng.com jsBody://{test.js}# 如果是html,则会自动加上 script 标签在追加到响应内容,如果是js,则会自动追加到js文本后面
www.ifeng.com jsAppend://{test.js}
复制代码

同样可以对 css 做这样的操作。 {}涉及到 values 的使用,具体参考下面的规则操作符和操作值。 whistle的功能总共有那些呢?可以参看协议列表

filter和ignore

ignore 用于忽略指定协议的匹配。whistle 支持的所有协议可以参看上面提到的协议列表。

pattern ignore://protocol1|protocol2|protocolN  # 忽略几种协议
pattern ignore://*  # 忽略所有协议
pattern ignore://*|-protocol1|-protocol2|-protocolN # 忽略这些以外的协议
复制代码

来看些实例:

# 表示www.example.com/test/yyy及其路径忽略host和socks规则
www.example.com/test/yyy ignore://host|socks
# 表示wwww.example.com/test/abc及其路径最多只保留socks规则
www.example.com/test/abc igore://*|-socks
复制代码

filter用来过滤已经匹配的规则,主要有两种用法:

  1. excludeFilter表示从已匹配结果中排除满足过滤条件的。
  2. includeFilter表示已匹配结果中只有满足过滤条件的是有效的。
www.test.com 127.0.0.1:8080 excludeFilter://*/cgi-bin excludeFilter://m:get excludeFilter://m:/^c/
复制代码

上面用到了m:,这是用来匹配 method 的方法,还有其他一些匹配方法:

  1. m:name,name为方法名称或正则表达式,表示匹配对应方法
  2. i:ip,ip表示具体客户(服务)端ip或匹配ip的正则表达式
  3. clientIp:ip,ip表示具体客户端ip或匹配ip的正则表达式
  4. serverIp:ip,ip表示具体服务端ip或匹配ip的正则表达式
  5. s:code,code表示响应状态码,或正则表达式
  6. h:name=pattern,匹配请求或响应头字段 name,pattern为该字段对应值里面的关键字或正则表示
  7. reqH:name=pattern,同上,但只会匹配请求头
  8. resH:name=pattern,同上,但只会匹配响应头
  9. b:pattern,匹配请求内容,pattern为内容的子字符串(不区分大小写),或正则表达式

而上面的*/cgi-bin用到的是通配路径,这样的用法在配置 rules 时经常需要,具体用法参见下面的匹配模式

规则操作符和操作值

上面的规则中写道jsAppend://{test.js},这里用到了{}。在配置规则时,可以使用三种操作符:{} () <>

而whistle的操作值可以分两类,字符串和JSON对象。由{}括起来会被当做 JSON,其他情况会当做字符串。

下面结合例子来看。

# '{}' 用于使用values中的key。(values用来设置键值对,在web界面可以方便的探索)
www.example.com resBody://{index.html}  // 'index.html'是一个key# '()' 用于直接在规则中插入值,可以插入字符串或者json
www.baidu.com resBody://({"delay":6000,"body":"1234567890"})
# www.baidu.com 会返回一个括号中的json。www.baidu.com urlParams://(test=1&token=0)
# www.baidu.com 会被替换为 www.baidu.com?test=1&token=0
# 注意,这种写法不可以包含空格# '<>'的作用是阻止自动拼接
www.ekwing.com/resource/exam file://D:/svn-projects/exam/resource
www.ekwing.com/resource/exam file://<D:/svn-projects/exam/resource># 第一种方式,www.ekwing.com/resource/exam/hello/hello.css 会被替代为 file://D:/svn-projects/exam/resource/hello/hello.css ,这就是whistle 默认的自动拼接。
# 第二种情况,www.ekwing.com/resource/exam/hello/hello.css 会被替代为 file://D:/svn-projects/exam/resource,因为这里自动拼接失效了。
复制代码

操作值除了可以利用 {}()两种操作符写入到 rules 当中以外,还有下面几种方式。

  1. 本地文件
 www.baidu.com resBody:///User/docs/test.txt# windowswww.baidu.com resBody://E:\docs\test.txt
复制代码
  1. 内联多行
www.test.com/index.html file://{test.html}``` test.html
Hello world.
Hello world1.
Hello world2.
```
复制代码

甚至可以嵌套使用:

www.test.com/index2.html reqScript://{test.rules}
``` test.rules
* file://{test.html}
``` test.html
reqScrip,
reqScript,
```
```
复制代码

这种方法有点像 values,但是优先级要高于 values。

  1. 模板字符串

whistle 支持像 es6 语法中的模板字符串 ``:

www.test.com http://`www.test.com?${reqCookie.cookieName}`
www.test.com/api http://`${clientIp}:8080`  # clientIP会被替换成请求方的IP
复制代码

模板字符串结合操作符 {} 来使用:

www.baidu.com resBody://`{test.json}`
复制代码

对应在 values 当中,有个 key 为 'test.json' 的值为:

{"url": "${url}","port": "${port}","version": "${version}","search": "${url.search}","query": "${url.query}","queryValue": "${url.query.name}","host": "${url.host}","hostname": "${url.hostname}","path": "${url.path}","pathname": "${url.pathname}","reqId": "${reqId}","now": ${now},"method": "${method}","xff": "${reqHeaders.x-test}","other": "${reqHeaders.other}","cookie": "${reqCookie}","cookieValue": "${reqCookie.cookieName}","clientIp": "${clientIp}"
}
复制代码

模板字符串中支持 replace 操作:

www.test.com http://`www.test.com?${url.query.replace(/ho/g, 'hello')}`
复制代码

匹配模式

要玩转whistle,除了了解上面的各种功能之外,还需要搞清楚匹配模式

whistle 的匹配模式可以分为 域名路径正则精确匹配通配符匹配

域名和路径匹配

www.test.com 127.0.0.1http://www.test.com 127.0.0.1 # 限制http协议才匹配www.test.com:8888 127.0.0.1 # 8888端口www.test.com/hello 127.0.0.1http://www.test.com/hello 127.0.0.1 # 限制http协议才匹配www.test.com:8888/hello 127.0.0.1 # 8888端口
复制代码

正则匹配

正则语法跟js的正则表达式一致,不支持/reg/g。可以把匹配的部分子串作为参数传到 operatorURL 中,一样是通过()$1 表示第一个 () 中的子串,可以这样匹配 9 个子串,$1...$9$0被用来表示整个匹配的url。

/mapi.ekwing.com\/([a-z]+).js/ 127.0.0.1:8080/$1.js
复制代码

精确匹配

路径匹配时默认会自动匹配路径及其子路经,不想要这样的时候,就可以用精确匹配。

$www.test.com/hello 127.0.0.1
复制代码

这样,www.test.com/hello/world 不会被匹配。

通配符匹配

通配符匹配是作为简化正则匹配而存在的,^限制开始位置,*就是通配符,$可以用来限制结束位置。也支持$0,$1...$9

通配符的位置和个数的规则有些复杂:

  • 如果通配符串在请求url的protocol里面,不管是一个还是多个 * 都只能匹配 [a-z\d]*
  • 如果通配符串在domain里面,一个 * 表示匹配 [^.],两个及以上的 * 表示匹配 [^.]*
*.test.com file:///User/xxx/test  # 只匹配test.com的子域名,不包括test.com**.test.com file:///User/xxx/test # 对子域名也生效
复制代码
  • 如果通配符串在path里面,一个 * 表示匹配 [^/]?,两个及以上 * 表示匹配 [^/]**在path中时,rule 必须以 ^ 开头
^test.com/hi/**/ file:///User/xxx/test
# 会匹配 test.com/hi//  test.com/hi/jk/  test.com/hi/jk/hi/^test.com/hi/*/ file:///User/xxx/test
# 会匹配 test.com/hi//  test.com/hi/jk/  不匹配test.com/hi/jk/hi/
复制代码
  • 如果通配符串在query里面,一个 * 表示匹配 [^&]?,两个及以上的 * 表示匹配 [^&]**在query中时,rule 必须以 ^ 开头
^test.com/hi?**a=2 file:///User/xxx/test
# 会匹配 test.com/hi?a=2 test.com/hi?jk=3&a=2  test.com/hi?jk=3&b=78&a=2^test.com/hi?*a=2 file:///User/xxx/test
# 会匹配 test.com/hi?a=2 test.com/hi?jk=3&a=2  不匹配test.com/hi?jk=3&b=78&a=2
复制代码

混合开发调试

本地开发调试

以 VUE 为例。

真机连接本地开发环境(开发时调试)

  1. devServer 不需要设置 host 等,但是需要设置 disableHostCheck:
devServer: {disableHostCheck: true
}
复制代码
  1. 在 whistle 中设置 rules:
www.test.com/hello/basepage localhost:8080/basepage
复制代码

有时候 localhost 不生效的话,尝试用本机IP代替。

  1. 给移动端 wifi 设置代理,代理地址为 {本机IP}:8899

  2. 如果移动端是请求https,参照这里进行设置。

注意:上面的例子,www.test.com/hello/basepage被代理后,本地 vue router 解析到的 path 仍然是 hello/basepage 而不是 basepage

bug调试,真机可用

如果需要真机连接到本机资源:

  1. 设置publicPath,然后 build。
  2. 在 whistle 中代理 html 和各类静态资源:
www.test.com/hello/basepage file://D:/projects/project-name/dist/index.html
www.test.com/your-public-path file://D:/projects/project-name/dist
复制代码

调试工具:

  1. whistle 自带的 weinre 和 log。当然手机要先代理到 whistle。
www.test.com weinre://test
# 像浏览器的 devtools 那样查看和修改页面结构www.test.com log://test
# 可以在 network 的log栏查看页面的log,也可以利用操作值注入自定义 js: log://{test.js},如果你喜欢将调试信息直接输出在手机屏幕上,可以注入微信的vConsole.js,但不可以和weinre一起用
复制代码

weinre:

log:

如果你嫌弃weinre用的不如devtools顺手,可以看看m-console。 2. 利用chrome inspect 连接 android,可以直接使用devTools,只是连接设置麻烦些。相应的,safari 也可以直接连接 iphone 进行调试。

机型bug调试(无真机)

有时候会遇到某一机型才有的bug,而刚好手头真机都不能重现问题。始终把真机调 bug 作为主要手段会是最好的选择,所以 android 测试机应该至少覆盖到国产机中那些高度定制原生android系统的品牌(比如华为、小米、魅族等)。

尝试模拟器

考虑原生系统问题(ios和原生android版本),尝试用同版本模拟器尝试。

本地模拟器

使用本地模拟器,同样可以像真机那样安装APP,可以设置代理,可以利用js调试,或者用 chrome 或者 safari 直接连接调试。

  • ios ios模拟器必须依赖mac,PC用户最多可以远程连接mac上的模拟器,这个方法需要PC安装 Visual Studio,与mac连接。然后启动ios模拟器即可调用远程的ios模拟器。

如果不是用 mac 开发,公司内部又没有把mac作为公用开发主机的情况,上面的连接方法其实也还是需要ios开发同事的配合,又何妨大家坐到一起解决这个问题呢。

  • android

android模拟器可以自行下载 android studio,然后 create 相应的 virtual device。

线上模拟器

appetize.io是个不错的提供线上模拟器的网站,可以方便的上传app安装,在网页上进行操作。免费用户有每个月100分钟的使用权,在机型类bug不多的情况,还是足够的。

这种情况就不方便使用代理了,可以利用像 vConsole 这样的工具,直接在模拟器上查看问题。

云真机

通过上面模拟机的尝试,可能会有些 bug 怎么样都还原不了。对于 android 市场那么多国产自家系统的情况,很有可能出现非真机不可的情况,当然随着 webview 越来越好,这种情况也会越来越少。

目前阿里和腾讯都有提供云真机服务。试过腾讯的云真机,同样是上传安装包,然后网页端可以操作手机,另外利用本地手机操控远程手机功能,体验还不错,注册就有30分钟免费。这样的解决方案非常适合小型互联网公司。

转载于:https://juejin.im/post/5c7f6d2be51d451581087134

利用 whistle 进行混合开发调试相关推荐

  1. FreeCAD C/C++/Python混合开发/调试方案

    FreeCAD C/C++/Python混合开发/调试方案 济南友泉软件有限公司 本文主要讲述在Visaul Studio 2019中混合调试FreeCAD C/C++/Python代码的环境配置方法 ...

  2. 【Flutter】Flutter 混合开发 ( Dart 代码调试 | Flutter 单独调试 | 混合模式下 Flutter 调试 )

    文章目录 前言 一.单独运行 Flutter 代码时调试 Dart 代码 二.混合模式下 Flutter 调试 Dart 代码 三.相关资源 前言 Flutter 混合开发集成步骤 : ① 在 And ...

  3. 利用Nginx轻松实现Ajax的跨域请求(前后端分离开发调试必备神技)

    利用Nginx轻松实现浏览器中Ajax的跨域请求(前后端分离开发调试必备神技) 前言 为什么会出现跨域? 造成跨域问题的原因是因为浏览器受到同源策略的限制,也就是说js只能访问和操作自己域下的资源,不 ...

  4. 开发测试技巧|辅助开发调试:goolge谷歌浏览器利用F12在控制台输入脚本实现表单自动填充

    一个开发测试技巧的指引和截图,利用google浏览器的F12调试和Console执行,注入JavaScript脚本实现表单的自动填充和测试. 执行的JS脚本. - 文本  隐藏/显示 function ...

  5. flutter混合开发怎么调试

    热重启/重新加载 大家在写纯Flutter应用的时候,知道是有热重启/重新加载功能的,但是在做混合开发的过程中,你会发现热重启/重新加载功能失效了.那么如何在混合开发中开启热重启/重新加载功能呢? 首 ...

  6. 移动端H5混合开发设置复盘与总结

    此篇接上一篇: 移动端H5混合开发,Touch触控,拖拽,长按, 滑屏 实现方案 https://www.cnblogs.com/buoge/p/9346699.html app 场布设置已经上线了, ...

  7. Hybrid混合开发学习笔记(1)混合应用开发定义和常见问题

    一.什么是混合应用 混合应用是指同时使用前端技术与原生技术开发的 App.通常由前端负责大部分界面开发和业务逻辑,原生负责封装原生功能供前端调用,二者以 WebView 作为媒介建立通信,从而既拥有 ...

  8. Ionic实现混合开发--探索之旅

    混合开发是什么? 个人理解混合开发指的是编写一个项目将涉及原生APP的API封装成JS模块,以插件的形式可以引入或删除,从而可以实现利用HTML调用原生API,本质上是HTML调用封装API的JS模块 ...

  9. 使用Cocos进行2D和3D混合开发

    这是异名上手cocos后,正式开发上线的第一款游戏,用的引擎版本是v.2.2.0,游戏一共有6个场景,其中一个3D场景,4个2D场景,在这里做简单的一个复盘和回顾,因为需要我们平台的账号登录就不能给大 ...

最新文章

  1. ITK:使用最小最大曲率流平滑RGB图像
  2. 细节之中自有天地,整洁成就卓越代码
  3. stackexchange_通过Spring Social推特StackExchange –第1部分
  4. GCN-Based User Representation Learning for Unifying Robust Recommendation and Fraudster Detection
  5. 必须掌握的Python技巧(三)
  6. jquery 插件 国外
  7. 数据结构 顺序表的建立+折半查找(二分查找)
  8. 商城小程序源码|开源小程序商城完整源码附视频搭建教程
  9. JavaScript需要记的阿斯克码
  10. 如何使用TrueCrypt加密
  11. 私藏的google浏览器插件
  12. pdf打印机怎么添加并使用?
  13. GSM和GPRS区别
  14. vue2知识点:数据代理
  15. Android——仿淘宝头条垂直滚动广告
  16. 零基础想学习插画?入门从这里开始
  17. Adobe cc版安装
  18. kotlin!腾讯+字节+阿里面经真题汇总,挥泪整理面经
  19. 店宝宝谈男士护肤美妆:千亿风口,巨头争锋
  20. Web开发和WSGI

热门文章

  1. android应用程序设计答案,Android移动应用程序设计智慧职教MOOC答案
  2. 4274. 【NOIP2015模拟10.28B组】终章-剑之魂
  3. java8历史版本下载地址
  4. 使用Python统计历年来各种英语高考题中单词的出现频数
  5. uos命令_UOS与Deepin OS区别详解
  6. uni-app开发小程序,笔记记录6 商品详情页
  7. 从招式与内功谈起——设计模式概述(三)
  8. java画五角星_java 画五角星 填充五角星
  9. Excel 甘特图 一行公式 极简版
  10. 明日之后怎么跳过实名认证_明日之后,怎么能跳过教学