前端5月30日 22:56
whistle 代理工具适合解决哪些前端调试问题?whistle 是基于 Node.js 的本地代理调试工具,常用来抓包、改请求、改响应、做接口 Mock、切换测试环境和调试移动端流量。它不像 Charles、Fiddler 那样主要依赖图形化操作,而是把很多能力放进规则文本里,适合前端团队沉淀一套可复制的调试方案。这个取舍很现实:规则可共享、可复用,但第一次配置代理、证书和规则时更容易出错。
安装一般只需要 Node 环境:
```bash
npm install -g whistle
w2 start
w2 status
```
启动后默认控制台是 `http://127.0.0.1:8899`。浏览器或手机把 HTTP/HTTPS 代理指向运行 whistle 的机器和 8899 端口,就能看到请求列表。HTTPS 调试必须安装并信任根证书,否则只能看到 CONNECT 隧道,看不到明文请求和响应。
常见规则可以这样写:
```txt
api.example.com 127.0.0.1:3000
https://api.example.com/user file:///Users/me/mock/user.json
www.example.com resHeaders://{cors}
```
第一行适合把接口转到本地服务,第二行适合固定 Mock 响应,第三行常用于临时验证跨域响应头。whistle 适合快速定位和验证问题,但不适合替代正式网关、灰度平台或线上流量治理。规则越多,越要按项目和场景分组,否则后来的人很难判断异常响应来自后端,还是被本地代理改过。
## 追问
### whistle 和 Charles、Fiddler 怎么选?
如果只是偶尔看请求、导出 HAR 或给测试复现问题,Charles 这类图形化工具更容易上手。whistle 更适合开发团队,因为规则可以复制到文档,也方便做 Mock 和转发。它的边界是本地环境依赖更强,Node、系统代理、证书任一环节错了都会影响结果。实际项目里可以开发用 whistle,非技术同学继续用图形化抓包工具。
### HTTPS 抓包为什么经常看不到响应内容?
最常见原因是没有安装或信任 whistle 的 HTTPS 根证书,浏览器只把请求当作加密隧道转发。第二个坑是 App 做了证书锁定,即使系统信任根证书也会拒绝中间人证书。还有一种情况是代理只配到浏览器,没有配到手机、模拟器或命令行进程。排查时先用普通 HTTPS 页面验证证书链,再调试目标 App。
### 用 whistle Mock 接口有什么边界?
Mock 适合验证前端分支、异常态和字段兼容,比如空列表、权限不足、接口超时。它不能证明真实接口契约完全正确,因为 Mock 数据很容易落后于后端变化。踩坑最多的是只 Mock 成功响应,结果上线后 401、429、500 分支没人处理。比较稳的做法是把常见错误码也做成规则,联调结束后再回真实环境验证一次。
### 移动端调试时需要注意什么?
手机代理地址要填电脑局域网 IP,不能填 `127.0.0.1`。如果公司网络有隔离策略,手机可能连不到电脑的 8899 端口,这时要换热点或确认防火墙放行。HTTPS 调试还要在手机上安装并信任证书,iOS 需要额外开启完全信任。调完后记得关闭手机代理,否则离开办公网络后会出现网页都打不开的假故障,也会误导后续排查。标签
Whistle
Whistle Proxy 是一个开源的网络调试代理工具,主要用于捕获和修改 HTTP(S) 网络请求。它支持多种平台,包括 Windows、Mac 和 Linux。Whistle Proxy 常被用于前端开发和测试中,以调试和优化应用程序的网络请求。

前端5月30日 22:48
Whistle 如何做接口数据模拟,resBody 和 resScript 怎么选?Whistle 做数据模拟,最常见的目标不是“造一份假数据”这么简单,而是让前端在后端未完成、接口异常、网络慢、登录态变化时都能继续开发。选方法时可以先问一句:这个响应是固定的,还是要根据参数、请求头、登录状态动态变化?固定数据用 `resBody` 和 Values 更省事,动态逻辑再上 `resScript` 或插件。
## 固定响应用 resBody
如果只是让某个接口返回一段稳定 JSON,`resBody` 是成本最低的方式。它适合登录信息、配置开关、列表空态、错误码等场景。为了可维护,不建议把很长的 JSON 直接写在规则行里,最好放到 Values 文件中。
```text
# 简短响应可以直接写
api.example.com/api/ping resBody://{"code":0,"data":"pong"}
# 复杂响应引用 Values
api.example.com/api/user resBody://{mock-user.json}
```
```json
{
"code": 0,
"data": {
"id": 1001,
"name": "测试用户",
"roles": ["admin"],
"vip": true
}
}
```
## 动态响应用 resScript
当响应需要读取 query、body、cookie,或者要模拟分页、随机失败、延迟时,`resScript` 更合适。脚本里应该显式设置 `Content-Type`,并处理缺省参数,否则前端拿到的响应可能和真实接口差异太大。
```javascript
module.exports = function(req, res) {
const page = Number(req.query.page || 1);
const size = Number(req.query.size || 10);
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
code: 0,
data: {
list: Array.from({ length: size }, (_, i) => ({
id: (page - 1) * size + i + 1,
title: `mock item ${i + 1}`
})),
page,
total: 86
}
}));
};
```
```text
api.example.com/api/list resScript://{mock-list.js}
```
## 异常和慢接口也要模拟
只模拟成功态是不够的,真实联调里更容易出问题的是超时、空列表、权限失败、字段缺失。可以准备几套 mock:success、empty、error、timeout,让前端页面在这些状态下都跑一遍。这样做比等后端临时改数据稳定,也更容易在评审前发现边界问题。
```javascript
module.exports = function(req, res) {
const type = req.query.type || 'success';
res.setHeader('Content-Type', 'application/json');
if (type === 'timeout') {
return setTimeout(() => res.end(JSON.stringify({ code: 0, data: [] })), 3000);
}
if (type === 'error') {
res.statusCode = 500;
return res.end(JSON.stringify({ code: 500, message: 'mock server error' }));
}
res.end(JSON.stringify({ code: 0, data: [{ id: 1, name: 'ok' }] }));
};
```
## 多人协作时怎么放 mock 数据?
团队共用 mock 不要散落在每个人的 Whistle 面板里,建议放进仓库并按业务目录组织。规则文件可以只写入口,mock 文件按接口域名或业务模块归档,例如 `mock/user/profile.json`、`mock/order/list.js`。这样评审时能直接看到字段变化,也方便后端一起确认返回结构。公共 mock 还可以配一份变更记录,说明字段新增、删除和默认值变化,避免旧页面继续依赖已经废弃的字段。规则文件只保留入口,具体 JSON 和脚本放在 `mock/user`、`mock/order` 之类的目录。每个 mock 文件最好说明对应接口、字段含义和适用场景,避免后端字段变了而 mock 还在误导前端。对于登录、权限、金额这类敏感链路,还要保留一份失败态样例,否则页面只在成功路径上好看,真实联调时很容易暴露遗漏。
## 追问
### resBody 和 Values 应该怎么选?
短小、一次性的响应可以直接写 `resBody`,超过几行的 JSON 建议放 Values。取舍是内联写法最快,但可读性和复用性很差。边界是包含数组、嵌套对象或多人复用的数据,基本都应该拆成文件。踩坑是 JSON 里引号转义写错,规则看似保存成功,实际响应格式已经坏了。
### 什么时候必须用 resScript?
只要响应依赖请求参数、分页、登录态、时间或随机异常,就应该考虑 `resScript`。取舍是脚本更灵活,但也更像一段小服务,需要处理异常和维护逻辑。边界是不要在脚本里实现完整后端业务,否则 mock 会变成另一套难维护系统。踩坑是脚本返回字段和真实接口越来越不一致,前端在 mock 下正常,上测试环境马上报错。
### 要不要模拟失败和超时?
要,尤其是移动端弱网、权限过期、空数据这些用户很容易遇到的状态。取舍是多准备几套 mock 会增加工作量,但能提前发现 loading、重试、错误提示是否合理。边界是不要为了覆盖所有理论错误码而无限膨胀,优先模拟产品真的会展示差异的状态。踩坑是只测成功响应,结果接口 500 时页面白屏,直到上线前才发现。
### mock 数据应该由前端还是后端维护?
初期可以由前端维护,因为前端最需要快速推进页面;接口稳定后最好和后端一起确认字段。取舍是前端维护速度快,后端确认准确性高。边界是涉及金额、权限、状态机的字段不能凭感觉编,必须和接口文档对齐。踩坑是 mock 里的枚举值写成了前端自创格式,后端真实返回后所有判断都失效。
### 复杂模拟要不要做成插件?
如果只是几个接口,`resScript` 已经够用;如果要统一管理大量场景、提供 UI 切换、记录请求,插件会更合适。取舍是插件体验更完整,但开发和发布成本更高。边界是团队复用、长期维护、需要状态管理时才值得插件化。踩坑是把简单 mock 过早做成插件,最后每次改一个字段都要发版,反而拖慢联调。前端5月30日 22:48
如何开发 Whistle 插件,基本目录和入口逻辑怎么设计?开发 Whistle 插件时,先别急着写复杂的拦截逻辑。一个好插件至少要回答三件事:它提供什么协议或规则能力,配置从哪里来,出错时怎样不影响正常代理。插件适合做团队可复用的能力,比如统一鉴权头、动态 mock、请求审计、环境面板;如果只是临时改一个接口,用普通 rules 和 values 更轻。
## 插件项目应该长什么样?
Whistle 插件本质上是一个 npm 包,包名通常使用 `whistle.xxx` 或团队约定的插件名。最小结构包括 `package.json`、入口文件、可选的 rules、values、README。入口文件负责注册服务逻辑,配置文件负责描述插件名称、菜单、规则等元信息。
```bash
mkdir whistle.demo-helper
cd whistle.demo-helper
npm init -y
mkdir lib test
touch index.js README.md
```
```json
{
"name": "whistle.demo-helper",
"version": "0.1.0",
"main": "index.js",
"whistleConfig": {
"name": "demo-helper",
"description": "team debug helper"
}
}
```
## 入口逻辑怎么写?
插件入口不要把所有事情都塞进一个巨大函数。建议把路由、配置读取、数据生成、错误处理拆开,入口只做组装。请求处理时要注意异步错误,任何未捕获异常都可能让调试体验变得很差。
```javascript
module.exports = function(server, options) {
server.get('/cgi-bin/ping', function(req, res) {
res.json({ ok: true, name: 'demo-helper' });
});
server.on('request', function(req) {
req.headers['x-debug-from'] = 'whistle-plugin';
});
};
```
这个例子只演示结构,真实项目里还应该把 header 名称、开关和目标域名做成配置,而不是写死。插件越通用,越要减少默认侵入性,让使用者通过规则明确启用。
## 在规则里如何启用插件?
安装本地插件可以用 `npm link` 或 Whistle 的安装命令。这里要先约定插件名称和规则写法,否则同一个插件在不同同学机器上可能出现“装了但没命中”的情况。建议 README 里放一条最小可验证规则,再配一个 `/cgi-bin/ping` 检查入口,避免把安装问题误判成业务代理问题。调试阶段推荐本地链接,发给团队使用前再发布到私有 npm 或写清楚安装方式。规则里通过 `plugin://` 或插件提供的协议启用,具体取决于插件能力设计。
```bash
npm link
w2 install demo-helper
w2 restart
```
```text
# 只对指定接口启用插件,避免全局污染
api.example.com/api/order plugin://demo-helper
```
## 插件里常见能力怎么拆?
如果是动态 mock,建议把数据模板、参数解析、延迟和错误比例拆成独立模块。目录上可以保留 `lib/mock`、`lib/config`、`lib/routes` 这类清晰边界,让入口文件只负责装配。这样后续增加新接口时,不会把所有逻辑都堆进 `index.js`。如果是请求审计,建议只记录必要字段,例如 URL、方法、状态码、耗时,不要默认落敏感 header 和 body。如果是团队面板,可以提供 `/cgi-bin/*` 接口给前端页面读取配置,但要避免无鉴权暴露内部信息。
## 追问
### 什么时候该写插件,什么时候只写规则?
一次性的 host、mock、header 修改用规则更合适,写插件反而增加维护成本。取舍在于插件能复用、可封装复杂逻辑,但发布、版本和兼容性都要有人负责。边界可以这样定:需要参数化、多人复用、包含 UI 或复杂状态时再考虑插件。踩坑是为了一个临时接口写插件,最后没人维护,Whistle 升级后还会拖累团队环境。
### 插件默认要不要全局生效?
通常不要,默认全局生效很容易误伤无关请求。取舍是全局生效配置简单,但排查问题时很难判断某个 header 或响应是不是插件改的。边界是审计、日志类插件可以全局观察,但修改请求或响应的逻辑最好通过规则显式启用。踩坑是插件给所有请求加了测试 header,结果第三方接口因为非法 header 拒绝访问。
### 插件配置应该放在哪里?
稳定默认值可以放 `package.json` 或代码常量,团队可变配置建议放 rules、values 或单独配置文件。取舍是代码内置最可靠,但每次调整都要发版;外部配置灵活,但需要校验和文档。边界是密钥、token、生产 Cookie 不应该进入插件包。踩坑是插件读取不到配置时静默使用默认生产域名,调试请求被转到了错误环境。
### 插件如何处理错误才安全?
插件内部要捕获异步错误,并给出可观察的日志或降级响应。取舍是直接抛错能尽快暴露问题,但会影响代理链路;降级更稳,但不能把错误吞得毫无痕迹。边界是 mock 类插件可以返回明确错误,审计类插件失败时应尽量不阻塞原请求。踩坑是读文件、查数据库这类操作用同步阻塞方式写在请求路径里,流量一大 Whistle 控制台也会变卡。
### 本地插件怎么给团队使用?
开发阶段用 `npm link` 最快,团队使用建议发布到私有 npm,并固定版本号。取舍是本地链接便于调试,但每个人机器状态不同;包管理方式更稳定,但需要发版流程。边界是不要让团队依赖某个同学电脑上的本地路径。踩坑是 README 只写了安装命令,没有写规则示例和验证方法,新同学装完也不知道插件是否生效。前端5月30日 22:48
如何用 Whistle 调试移动端 App,代理和证书怎么配置?用 Whistle 调试移动端应用,本质是让手机的 HTTP/HTTPS 流量先经过电脑上的 Whistle,再由 Whistle 转发到真实服务或 mock 服务。步骤不难,难点通常在三处:手机连不到电脑代理、HTTPS 证书没被系统信任、App 自己做了证书绑定。只要按顺序排查,移动端抓包和改包会稳定很多。
## 先确认电脑端 Whistle 可访问
电脑上启动 Whistle,默认端口是 `8899`。如果团队里端口有冲突,可以显式指定端口,但手机代理里也要填同一个端口。启动后先在电脑浏览器打开 `http://127.0.0.1:8899/`,确认控制台能进入。
```bash
w2 start -p 8899
w2 status
# macOS 查看局域网 IP
ipconfig getifaddr en0
# Windows 查看 IPv4
ipconfig
```
手机和电脑必须在同一个网络里,常见地址类似 `192.168.1.23` 或 `10.0.0.8`。如果公司 Wi-Fi 开了客户端隔离,手机即使和电脑连同一个热点,也可能访问不到电脑端口,这时可以换个人热点或使用 USB/模拟器方案。
## 手机代理怎么配?
iOS 进入当前 Wi-Fi 的详情页,在 HTTP 代理里选择“手动”,服务器填电脑局域网 IP,端口填 `8899`。Android 一般在 Wi-Fi 的“修改网络”或“代理”设置里填写同样的信息,不同厂商入口会有差异。配置完成后,用手机浏览器访问 `http://电脑IP:8899/`,能打开 Whistle 页面才说明链路通了。
如果手机访问不了,先不要急着改规则。检查电脑防火墙、VPN、公司安全软件、端口是否监听在正确网卡上。也可以在电脑上临时换端口启动,例如 `w2 start -p 8888`,排除端口被占用的问题。
## HTTPS 证书怎么安装?
HTTP 请求能看到不代表 HTTPS 能解密。要查看 HTTPS 内容,需要在手机上安装并信任 Whistle RootCA。手机访问 `http://电脑IP:8899/`,进入 HTTPS 页面下载证书;iOS 安装描述文件后,还要到“关于本机 - 证书信任设置”里开启完全信任;Android 则需要安装为用户证书,部分高版本系统对 App 信任用户证书有限制。
```text
# 移动端调试常用规则示例
api.example.com/api/user resBody://{mobile-user.json}
m.example.com reqHeaders://{mobile-headers.json}
app.example.com/api/* host 192.168.1.23:3000
```
## 如何验证规则真的生效?
先用手机浏览器访问一个简单接口,看 Whistle 的 Network 面板是否出现请求。再加一条低风险的响应头或 mock 规则,确认响应确实被改写。不要一开始就调试复杂 App,否则你很难判断问题出在代理、证书、规则还是 App 网络库。
```json
{
"code": 0,
"data": { "from": "whistle-mobile", "login": true }
}
```
## 追问
### 手机访问不了 Whistle 控制台怎么办?
先确认手机和电脑在同一网段,再检查电脑防火墙是否拦截了 `8899` 端口。取舍上,关闭防火墙排查最快,但长期使用应该只放行 Whistle 端口而不是全关。边界是公司网络可能禁止设备互访,这种情况下继续改 Whistle 规则没有意义。常见踩坑是电脑开着 VPN,手机填的却是局域网不可达的虚拟网卡地址。
### 为什么 HTTPS 证书装了还是看不到内容?
可能是证书没有被完全信任,也可能是 App 不信任用户安装的根证书。取舍是浏览器调试成本最低,但真实 App 尤其是金融、支付类应用更可能做证书绑定。边界是 Whistle 不能绕过所有安全策略,遇到 certificate pinning 需要换调试包、关闭 pinning 或使用专门的测试构建。踩坑是只安装了证书文件,却忘了在 iOS 里开启“完全信任”。
### Android 能不能不用 Wi-Fi 代理?
可以在部分场景下用模拟器代理,或通过 ADB 做端口转发,但真实设备的系统代理仍然最直观。取舍是 Wi-Fi 代理配置简单,ADB 方案更适合本地开发机和模拟器联调。边界在于 `adb reverse tcp:8899 tcp:8899` 只能解决一部分访问方向问题,不等于所有 App 流量都会自动进 Whistle。踩坑是以为 USB 连上就能抓包,结果 App 仍然走移动网络或直连。
### 某些 App 请求完全不出现是什么原因?
可能是 App 没走系统代理、用了私有网络库、开启了 QUIC,或者请求走了 WebSocket/长连接。取舍是系统代理对 H5 和普通 HTTP 客户端很友好,但对强安全原生 App 不一定够用。边界是生产包的网络安全策略通常更严格,调试时最好使用测试包。踩坑是只盯着 HTTPS 证书,忽略了 App 可能根本没有把流量发到代理。
### 调试结束后需要恢复哪些设置?
至少要关闭手机 Wi-Fi 代理,必要时删除或停用 Whistle 证书,并停止本机 Whistle 服务。取舍是保留代理下次调试更省事,但日常使用容易导致网络变慢或访问失败。边界是公共网络和非调试场景不要长期挂代理。踩坑是下班后手机还连着电脑代理,第二天电脑没开,手机所有网页都打不开。前端5月30日 22:48
Whistle 规则如何管理,团队协作时怎样避免配置冲突?Whistle 的规则管理不要只理解成“谁在网页里改几行配置”。个人调试时,Web 界面足够快;团队协作时,真正麻烦的是规则来源、环境切换、命名规范和回滚机制。如果这些没有约定,今天 A 同学为了联调把接口代理到本地,明天 B 同学拉到同一份规则后就可能误连错环境。
## 规则应该放在哪里管理?
日常临时调试可以直接打开 `http://127.0.0.1:8899/`,在 Rules 面板里写规则并保存,适合验证某个接口、替换一个静态资源、临时 mock 一段响应。它的好处是所见即所得,Network 面板马上能看到命中情况;缺点是改动容易散落在个人机器上,别人不知道你改了什么。
团队长期使用时,建议把公共规则放到 Git 仓库,个人规则留在本地。公共规则只放稳定的域名代理、公共 mock、跨域头、常用环境入口;个人规则放本地端口、临时调试、风险较高的 host 覆盖。这样既能共享经验,也不会把每个人电脑上的实验配置带给全组。
```bash
# 常用启动与检查
w2 start -p 8899
w2 status
w2 restart
w2 stop
# 如果需要指定规则文件启动
w2 start -f ./rules-dev
```
## 规则文件怎么组织更适合协作?
一份可维护的规则文件,应该先按业务或环境分组,再按命中范围从小到大排列。更具体的路径规则放在前面,宽泛的通配符和正则放在后面,否则容易出现“看起来写了规则,但一直没命中”的问题。注释不要写成流水账,最好说明这条规则解决什么问题、谁在使用、什么时候可以删除。
```text
# user-service: 本地联调用户接口,owner: frontend-user
www.example.com/api/user host 127.0.0.1:3001
# mobile-h5: 移动端静态资源走测试 CDN
m.example.com/static/* host test-cdn.example.com
# mock: 登录态过期响应,仅用于异常状态验证
www.example.com/api/session resBody://{session-expired.json}
```
## 团队共享时推荐什么流程?
比较稳妥的方式是建一个 `whistle-rules` 仓库,把 `rules-dev`、`rules-test`、`values`、`README.md` 放进去。新同学克隆仓库后,用软链接或启动参数指向对应规则文件;改公共规则时走 Pull Request,至少让相关业务同学看一眼。不要直接让所有人共用同一个可写文件,否则一次错误保存就会影响整组。
```bash
git clone git@example.com:team/whistle-rules.git ~/whistle-rules
ln -sf ~/whistle-rules/rules-dev ~/.whistle/rules
w2 restart
```
## Values 和环境变量怎么配合?
Values 适合放可复用的 mock 数据和变量,例如本地域名、端口、通用响应体。环境差异很大的内容不要硬塞进一份文件,可以拆成 `values-dev.json`、`values-test.json`,再通过文档说明切换方式。敏感 token、Cookie、内网账号不要提交到仓库,最多提供字段模板。
```json
{
"localApi": "127.0.0.1:3001",
"corsHeaders": {
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true"
}
}
```
## 追问
### 公共规则和个人规则怎么划分?
公共规则放团队都需要、行为稳定、风险可控的配置,个人规则放本地端口、临时 mock 和实验性代理。取舍点在于共享越多,上手越快,但误伤范围也越大。边界可以定得很明确:会影响真实登录、支付、下单、生产域名的规则,默认不进公共文件。常见踩坑是把自己本地 `127.0.0.1` 的代理提交上去,别人一拉规则接口就全挂。
### 规则顺序冲突时怎么排查?
先在 Network 里看请求是否命中预期规则,再把精确路径放到通配符前面,必要时临时注释掉宽泛规则验证。取舍是规则写得越通用越省事,但排查时越难判断谁覆盖了谁。边界上,不建议用一个 `*.example.com *` 之类的大范围规则解决所有问题。踩坑最多的是正则和通配符混用后,以为后面的精确规则会覆盖前面的宽泛规则。
### 要不要把 whistle 规则纳入代码评审?
如果规则会影响多人联调,就应该评审,至少确认域名、路径、mock 数据和删除时间。取舍是评审会增加一点流程成本,但能减少半天都查不出的代理误配。边界可以放宽在个人规则和临时验证上,这类不需要走 PR。踩坑是没有 owner 的规则越积越多,半年后没人敢删,最后变成第二套隐形环境配置。
### 多环境切换用复制文件还是启动参数?
少量环境可以复制文件后 `w2 restart`,但团队协作更推荐保留多个规则文件,用启动参数或软链接切换。取舍在于复制文件直观,启动参数更可追溯。边界是不要在同一份规则里同时启用 dev、test、prod 三套代理,除非你能保证域名完全隔离。踩坑是切完环境忘记重启 whistle,或者浏览器缓存让你误以为规则没生效。
### 规则里能不能放敏感信息?
不建议放,尤其是 Cookie、Authorization、内部账号和生产 token。取舍是写进去调试最快,但一旦提交仓库或截图分享,泄露成本很高。边界是公共仓库只允许放示例值和字段结构,真实值放个人本地 Values 或环境变量。踩坑是 mock 登录态时顺手贴了真实 Cookie,后来被多人复用,排查权限问题会非常混乱。前端5月30日 22:48
whistle 如何用脚本处理请求响应并避开常见坑?whistle 的脚本能力适合处理规则表达不了的逻辑,比如按请求参数动态改 header、根据用户身份返回不同 mock、给响应体追加字段,或者把线上接口临时改造成前端需要的数据形状。规则更像声明式配置,脚本则是命令式处理;能用规则解决的别急着写脚本,因为脚本越多,调试成本和副作用也越高。它的边界也很明确:脚本运行在代理链路里,任何慢逻辑都会拖慢请求,任何不严谨的匹配都可能影响无关流量。
先准备一个本地脚本文件,例如 `change-user.js`:
```javascript
module.exports = (req, res) => {
req.headers['x-debug-user'] = '10001';
};
```
在 Rules 中绑定到目标接口:
```txt
https://api.example.com/user reqScript:///Users/me/whistle/change-user.js
```
响应处理通常用于 mock 或修正字段,示例只处理 JSON,避免误伤图片、HTML 或二进制内容:
```javascript
module.exports = (req, res) => {
const type = res.headers['content-type'] || '';
if (!type.includes('application/json')) return;
const data = JSON.parse(res.body || '{}');
data.debug = true;
res.body = JSON.stringify(data);
};
```
脚本最好和规则一起放进项目的调试目录,文件名说明用途,例如 `mock-login-expired.js`、`add-debug-header.js`。团队协作时要写清楚启用条件,不要让别人打开 whistle 后默认命中你的个人调试逻辑。
## 追问
### reqScript 和 resScript 应该怎么选?
需要在请求发出前改 URL、header、cookie 或 body,就用 reqScript;需要在服务端返回后改状态码、响应头或响应体,就用 resScript。取舍点在于问题发生的位置:鉴权参数错了通常改请求,接口字段不满足前端联调通常改响应。踩坑最多的是在 resScript 里试图修正已经发出去的请求参数,这时后端早就处理完了。判断不清时先在 Network 里看请求和响应,确认要动哪一侧。
### 脚本里处理 JSON 响应要注意什么?
第一步永远是判断 `content-type`,不要默认所有响应都是 JSON。边界包括空响应、压缩响应、流式响应、图片和下载文件,这些内容被强行 `JSON.parse` 很容易报错或损坏。更稳的写法是只匹配明确接口,并对解析失败做兜底,不要让一个异常中断整个代理处理。调试阶段可以打印 URL 和错误信息,但长期使用要减少日志,避免控制台被刷屏。
### 为什么不建议所有 mock 都用脚本写?
脚本很灵活,但灵活也意味着行为不够直观。简单固定响应用 `resBody` 或 Values 更容易维护,复杂条件分支、按参数返回不同数据时再上脚本。取舍标准是“别人打开规则能不能一眼看懂”,如果必须读几十行 JS 才知道接口返回什么,维护成本就偏高。常见坑是脚本越写越像小服务,最后不如直接起一个本地 mock server。
### 脚本影响了无关请求怎么办?
先收窄 Rules 匹配范围,不要用过宽的域名或通配符挂脚本。脚本内部也可以二次判断路径、方法和参数,条件不满足立刻 `return`。边界是代理层没有业务上下文,不能只凭一个字段就假设请求属于某个页面。排查时先禁用脚本确认问题消失,再逐步恢复匹配条件和处理逻辑。
### 团队里怎么管理这些调试脚本?
建议把通用脚本放进仓库的 `debug/whistle` 目录,只提交脱敏、可复用的版本,个人临时脚本放在本机不共享。配置里不要写真实 token、内网账号或客户数据,必要时用环境变量或本地 Values 注入。取舍是共享脚本能提升联调效率,但也可能把个人调试假设扩散给全团队。每个脚本顶部写两三行用途、命中接口和关闭方式,比事后在群里解释更省时间。前端5月30日 22:48
whistle 如何捕获请求并快速过滤定位问题?whistle 捕获请求的核心流程是:启动本地代理,让浏览器、App 或命令行流量经过它,然后在 Network 面板查看请求、响应、耗时、头信息和匹配规则。它不像浏览器 DevTools 只看当前页面,而是能统一观察多端流量,尤其适合排查 H5、客户端内嵌页、Node 服务请求和第三方 SDK 调用。使用前要明确边界:whistle 只能看到走代理的流量,系统代理没配好、App 不信任证书、命令行绕过代理时,Network 面板自然不会出现请求。
先启动服务并打开管理页:
```bash
npm i -g whistle
w2 start -p 8899
open http://127.0.0.1:8899/
```
浏览器可以直接配置 HTTP/HTTPS 代理为 `127.0.0.1:8899`,命令行请求可以这样验证:
```bash
export HTTP_PROXY=http://127.0.0.1:8899
export HTTPS_PROXY=http://127.0.0.1:8899
curl -I https://example.com
```
如果要看 HTTPS 明文内容,需要安装并信任 whistle 根证书。证书只用于本机调试,别在公共设备或不可信网络里随便安装;调试结束后可以关闭代理,避免正常访问也继续经过 whistle。
Network 面板里最常用的是域名、路径、方法、状态码和关键字过滤。排查接口失败时,先用域名缩小范围,再用 `status:500`、`method:POST`、接口路径片段继续收窄。遇到请求太多的页面,直接清空列表后复现一次,比在几千条历史记录里搜索更可靠。
## 追问
### 为什么已经配置代理却抓不到请求?
先确认流量来源是否真的走了 `127.0.0.1:8899`,浏览器、系统、App 模拟器和命令行各有自己的代理设置。取舍上,浏览器调试最简单,移动端调试更接近真实场景但证书和网络环境更容易出问题。常见坑是 App 使用了证书锁定、系统代理被 VPN 覆盖,或者 Node 请求库显式禁用了代理。可以先用 `curl` 走代理验证 whistle 正常,再回到具体客户端排查。
### Network 里请求太多,怎么快速定位目标接口?
不要一上来搜索很短的词,比如 `api` 或 `user`,这会把噪音也带进来。更稳的做法是按域名、路径片段、请求方法、状态码逐层过滤,最后再看请求体或响应体。边界是过滤条件越多,越可能把真正的异常请求排除掉,所以每次收窄都要确认列表数量是否合理。踩坑时可以先清屏,再触发一次具体操作,让目标请求出现在最新的几条里。
### HTTPS 请求显示 CONNECT 或看不到响应体怎么办?
这通常是证书没有安装、没有被系统信任,或者客户端不接受用户证书。浏览器调试时安装 whistle 证书一般就够了,Android 7 之后的 App 可能还需要应用允许用户证书,部分金融或安全类 App 会做证书锁定。取舍是:普通业务调试可以信任本机证书,涉及敏感账号和生产数据时应尽量用测试环境。不要为了抓包去关闭应用安全校验并提交到正式包,这是非常典型的安全事故源头。
### 如何用 whistle 判断问题在前端还是后端?
先看请求是否发出、URL 和参数是否正确,再看后端返回的状态码、响应体和耗时。若请求没发出,多半是前端逻辑、跨域预检或网络配置问题;若请求正确但响应错误,就要看服务端日志或网关链路。一个实用取舍是临时用规则 mock 一个成功响应,如果页面恢复正常,说明前端渲染链路大概率没问题。反过来,如果 mock 成功响应页面仍异常,就要查前端数据解析或状态管理。
### 过滤和搜索有什么踩坑点?
过滤是为了缩小列表,搜索是为了在已有列表里找内容,两者不要混用。很多人只搜响应关键字,却忘了请求还没被捕获或已经被过滤条件排除,结果误以为接口没返回。另一个坑是缓存,请求可能直接走浏览器缓存,Network 里看不到你期待的接口变化。排查时可以禁用缓存、加随机参数,或者在 whistle 里观察状态码和响应头是否真的来自服务端。前端5月30日 22:48
whistle Values 如何管理多环境配置和 mock 数据?whistle 的 Values 可以理解成一份可复用的变量仓库,用来存放域名、端口、token、mock JSON、响应片段等配置。规则里用 `{key}` 引用后,同一份值可以被多条规则复用,切环境时只改 Values,不用把规则逐行改一遍。它最适合处理“规则稳定但数据经常变”的场景,比如本地、测试、预发三套接口地址,或者同一个接口在不同用例下返回不同响应。边界也要先说清楚:Values 不是数据库,不适合放大量动态数据,更不要放生产密钥;它解决的是代理调试里的配置复用问题。
常见启动方式如下,先确认 whistle 正常运行,再进入 `http://127.0.0.1:8899/` 管理界面。
```bash
npm i -g whistle
w2 start -p 8899
w2 status
```
在 Values 面板里可以创建 `env.json`,内容保持简单、稳定:
```json
{
"apiHost": "http://127.0.0.1:3000",
"testHost": "https://test.example.com",
"userId": "10001",
"profileMock": { "name": "Tom", "role": "admin" }
}
```
规则中再引用这些值:
```txt
^https://api.example.com/(.*) {apiHost}/$1
https://api.example.com/user?id={userId} resBody://{profileMock}
```
这个写法的好处是规则仍然表达“流量怎么转发”,Values 只负责“具体值是什么”。如果团队多人共用,建议把 key 命名成 `env.apiHost`、`mock.profile.admin` 这类层级语义,避免 `host1`、`data2` 这种几天后没人敢动的名字。
## 追问
### Values 和 Rules 应该怎么分工?
Rules 管流量匹配、转发、替换和注入,Values 管可复用的数据。取舍标准很简单:如果一段内容会被多条规则引用,或者经常随环境变化,就放到 Values;如果它只服务一条规则,直接写在 Rules 里反而更直观。踩坑最多的是把整套规则都“变量化”,最后打开规则只看到一堆 `{xxx}`,排查时必须来回切面板。Values 应该降低重复,不应该降低可读性。
### 多环境配置怎么切换最稳?
建议为不同环境建独立 Values,例如 `local.json`、`test.json`、`pre.json`,每份保持相同 key,只替换 value。这样规则文件不用变,切换时只启用对应 Values,团队成员也容易对齐。边界是同一时间不要启用多份同名 key 的 Values,否则后加载或更高优先级的值会覆盖前面的值,表现像“规则偶尔失灵”。如果必须临时覆盖,最好在 key 名里写清楚 `override`,用完立刻关闭。
### Values 里能不能放接口 mock 响应?
可以,尤其适合体积不大的 JSON 响应、错误码、空列表、权限状态等固定场景。取舍在于维护成本:几十行以内的 mock 放 Values 很方便,几百行甚至带复杂逻辑时,应该改用文件、插件或脚本处理。常见踩坑是 JSON 少了引号或多了尾逗号,规则没有明显报错,但响应内容就是不对。写 mock 时先用 JSON 校验工具检查,再用 Network 面板确认最终响应体。
### Values 适合保存 token 和账号信息吗?
临时调试 token 可以放,但不建议长期保存真实生产凭据。whistle 是本地代理工具,团队共享配置、截图或导出时很容易把敏感值带出去。更稳的做法是只保存占位符,例如 `{debugToken}`,真实值由个人本地单独维护,或者在脚本里从环境变量读取。边界是测试环境的低权限 token 可以接受,生产管理员 token 不应该进入 Values。
### Values 不生效时怎么排查?
先看 key 是否拼错,再看对应 Values 是否启用,最后看规则命中是否符合预期。可以把响应临时改成固定文本验证引用是否成功,例如 `resBody://{profileMock}`,比直接排查完整代理链更快。另一个坑是值里包含特殊字符、换行或 URL 参数时没有正确转义,导致规则解析和预期不同。排查时一次只改一个变量,并在 Network 里查看实际请求 URL、响应头和响应体。前端5月30日 22:48
whistle 支持哪些协议?HTTP、HTTPS、WebSocket 怎么代理?Whistle 常用于 HTTP 调试,但它能处理的并不只有普通 HTTP 请求。前端和移动端排查里,常见的是 HTTP、HTTPS、WebSocket、HTTP/2 以及 SOCKS 或上游代理。理解这些协议的差异,比背规则更重要:HTTP 明文好改,HTTPS 需要证书信任,WebSocket 建连后是长连接,HTTP/2 可能在代理链路里被降级。协议边界没弄清,规则看似正确,请求也可能不按预期走。
HTTP 最直接,可以替换 host、改请求头和响应体,适合本地联调和 Mock。
```txt
www.example.com host 127.0.0.1:8080
http://www.example.com/api/user resBody://{"code":0}
http://www.example.com/api/user reqHeaders://{"x-debug":"1"}
```
HTTPS 多了一层证书。浏览器先和代理建立 CONNECT,再由 whistle 解密转发;没有信任根证书时,只能看到隧道,看不到路径和响应。调试前先启动服务并按页面提示安装证书:
```bash
w2 start -p 8899
# 浏览器访问 http://127.0.0.1:8899,下载并信任根证书
```
HTTPS 的坑主要有三个:移动端证书信任策略不同;部分 App 做了证书固定;生产登录、支付链路不该随便关闭校验。调试时可以只匹配目标域名,不要用过宽规则影响全部流量。
WebSocket 也是 whistle 很有价值的场景。它先通过 HTTP Upgrade 建立连接,之后变成双向消息流,因此排查时既要看握手,也要看消息内容。
```txt
ws://socket.example.com host 127.0.0.1:7001
wss://socket.example.com host 127.0.0.1:7001
```
HTTP/2 和 SOCKS 更像链路兼容问题。很多代理工具会把 HTTP/2 在中间链路降到 HTTP/1.1,这通常不影响接口语义,但会影响多路复用、头压缩和性能判断。SOCKS 适合把流量再转给公司代理、远程调试机或特定网络出口,改包能力仍然发生在 whistle 这一层。
```txt
api.example.com socks://127.0.0.1:1080
api.example.com proxy://http://127.0.0.1:8888
```
## 追问
### HTTP 和 HTTPS 代理规则写法一样吗?
大部分匹配和改写规则看起来一样,但 HTTPS 能否生效取决于证书信任和解密权限。HTTP 请求是明文,whistle 可以直接看到路径、header 和 body;HTTPS 如果只建立了 CONNECT 隧道,就只能看到域名和连接信息。取舍是安全性和可调试性:本地排查可以信任证书,生产或敏感链路不要随意解密。遇到规则不生效,先确认是不是根本没拿到 HTTPS 明文。
### WebSocket 代理为什么有时只能看到连接,看不到消息?
可能是规则只命中了握手域名,没有命中实际的 wss 地址,也可能是客户端走了不同端口或备用域名。WebSocket 建连成功后是长连接,页面刷新、重连和心跳都会影响观察结果。另一个常见坑是消息被业务层压缩或加密,代理能看到帧,但看不懂业务内容。排查时先验证 Upgrade 状态,再看消息方向和重连次数。
### HTTP/2 被代理后降级会不会影响测试结论?
如果只是验证接口返回、Mock 数据和 header,通常影响不大。若你在排查性能、连接复用、服务端推送或 gRPC 类场景,降级就可能改变结论。whistle 更适合做功能调试和流量改写,不适合替代专门的协议性能分析工具。边界看测试目标:测业务语义可以接受,测协议特性就要谨慎。
### SOCKS、proxy 和 host 规则怎么选?
`host` 适合把目标域名指到本地或测试机,最直观也最常用。`proxy` 适合把请求交给另一个 HTTP 代理,`socks` 适合走公司网络、远程环境或特定出口。不要把三者叠太多层,否则失败时很难判断是哪一层断了。建议先用 `host` 跑通,再按网络限制加上游代理。
### 多协议混合项目应该怎么写规则?
不要用一个大规则覆盖所有域名,应该按协议和业务域名拆开。HTTP API、HTTPS 登录、WebSocket 推送、静态资源最好分别写,必要时加注释说明用途。这样做的成本是规则文件稍长,但排查时能快速关闭某一段,不会影响其他流量。尤其是移动端项目,登录和长连接经常共享域名,规则过宽很容易制造假故障。前端5月30日 22:48
whistle 如何和浏览器、IDE、构建工具一起调试?Whistle 和开发工具集成时,核心思路不是“装越多插件越好”,而是把它放在请求链路中最容易观察和改写的位置。DevTools 看页面行为,IDE 编辑规则,构建工具跑本地服务,whistle 统一接住请求。同一个接口问题可以从页面、代理、服务端交叉验证。取舍也很明显:链路越完整,排查能力越强,但配置层级越多,误配概率也越高。
最基础的集成是浏览器代理。Chrome、Edge、Firefox 都可配置系统代理,也可只给调试浏览器加启动参数。
```bash
w2 start -p 8899
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/tmp/chrome-whistle --proxy-server=http://127.0.0.1:8899
```
这种方式适合排查登录、Cookie、CORS、缓存和重定向。DevTools 是页面侧视角,适合看瀑布图和前端报错;whistle 是代理侧视角,适合改响应、替换 host、保存规则。HTTPS 调试要先安装 whistle 根证书,否则只能看到 CONNECT,无法看到明文请求。
IDE 集成更简单,重点是让规则文件进项目。VS Code 可以用普通文本编辑规则,WebStorm 可以同时配置 HTTP Client 和项目代理。团队协作时,建议把常用规则放进仓库:
```txt
# local-api.rules
api.example.com host 127.0.0.1:3000
static.example.com file:///Users/me/project/mock-static
https://api.example.com/debug reqHeaders://{"x-debug":"1"}
```
构建工具不要盲目再代理一次。Vite、Webpack、Next.js 都能转发 `/api`,如果它们和 whistle 同时改 host,排查会很绕。稳妥方案是:构建工具只跑前端页面,跨域、Mock、弱网和接口替换交给 whistle。
```js
// vite.config.js
export default {
server: { proxy: { '/api': { target: 'http://127.0.0.1:8899', changeOrigin: true } } }
}
```
## 追问
### 浏览器 DevTools 已经能看 Network,为什么还要 whistle?
DevTools 擅长观察,但不擅长批量改写和复用规则。whistle 可以把 host 替换、响应 Mock、请求头注入、弱网模拟保存成规则,下一次不用重新点一遍。两者不是替代关系,DevTools 看页面表现,whistle 控制网络入口。边界是性能分析仍然优先看 DevTools,因为它能关联渲染、脚本和资源加载时间。
### VS Code 插件是必须的吗?
不是必须,规则本质上是文本,能编辑、能保存、能被团队复用就够了。插件的价值主要是语法高亮和减少拼写错误,不应该依赖插件才能跑通流程。真正容易踩坑的是规则只存在某个人本机 whistle 里,换机器就复现不了。建议把关键规则文件放进项目,并说明启动端口和适用环境。
### Vite 或 Webpack 的 proxy 和 whistle 会冲突吗?
会,尤其是两边都配置了 `/api` 转发或 host 替换时,请求路径会变得不直观。一般建议本地开发服务器只服务前端资源,把接口层交给 whistle;如果项目已有 devServer proxy,就让它转到 whistle 统一分流。这样牺牲了一点配置简洁度,但换来更稳定的调试入口。排查时按浏览器、devServer、whistle、后端的顺序逐层确认。
### 和 Postman、curl 这类接口工具怎么配合?
接口工具可以直接把代理设成 `127.0.0.1:8899`,或者临时使用环境变量。这样请求会经过 whistle,便于复用同一套 Mock 和 header 规则。命令行可以这样跑:`HTTPS_PROXY=http://127.0.0.1:8899 curl https://api.example.com/user -k`。注意 `-k` 只适合本地调试,真实证书问题不能靠它掩盖。
### 团队共用 whistle 规则有什么风险?
最大风险是规则过期但没人知道,导致新人调试时命中了旧环境。另一个坑是规则过宽,例如只写 `example.com host 127.0.0.1`,把静态资源、登录和接口全改掉。团队规则应该小而明确,按场景拆分,并在注释里写清楚用途和失效条件。需要经常变化的个人规则,不要混进公共规则。前端5月30日 22:48
whistle 如何接入自动化测试并稳定 Mock 网络请求?Whistle 可以接入自动化测试,但它更适合作为“可控网络层”,而不是替代测试框架。Jest、Playwright、Puppeteer 负责断言和驱动浏览器,whistle 负责代理、Mock 和改包。这样测试代码不用侵入业务接口,也能复现弱网、跨域和接口异常。边界也要说清楚:如果只是单元测试,直接 mock 函数更轻;只有涉及浏览器真实网络、HTTPS 或 WebSocket 时,whistle 的价值才明显。
先把 whistle 作为测试前置服务启动,端口固定,避免 CI 和本机不一致。
```bash
npm i -D jest puppeteer
npm i -g whistle
w2 start -p 8899
w2 stop
```
浏览器侧只需要把代理指向 whistle。Puppeteer 的配置通常放在测试 setup 里,Playwright 也有类似的 `proxy` 选项。
```js
const browser = await puppeteer.launch({
headless: 'new',
args: ['--proxy-server=http://127.0.0.1:8899']
})
```
Mock 规则建议单独维护,不要散落在测试用例里。比如把线上 API 改到本地服务,或者直接返回固定 JSON:
```txt
api.example.com host 127.0.0.1:3000
https://api.example.com/user resBody://{"code":0,"name":"mock-user"}
https://api.example.com/user resHeaders://{"content-type":"application/json"}
```
在 CI 里要额外处理两个细节:第一,等待 whistle 真正启动后再跑测试,不能只 sleep 一秒就赌运气;第二,HTTPS 场景需要提前安装并信任 whistle 根证书。测试环境可临时加 `ignoreHTTPSErrors`,但它会掩盖证书链问题,不适合验证支付、登录链路。
## 追问
### Jest、Playwright 和 Puppeteer 该选哪个?
如果测试重点是函数和组件逻辑,Jest 足够,没必要引入 whistle。只要验证真实页面请求、跳转、Cookie 或跨域行为,就应该用 Playwright 或 Puppeteer 驱动浏览器,再让 whistle 接管网络。Playwright 在多浏览器和等待机制上更省心,Puppeteer 更贴近 Chrome 调试。取舍点是维护成本:端到端测试越真实,运行越慢,也越容易受环境影响。
### Mock 数据应该写在 whistle 规则里还是测试代码里?
稳定的接口替身适合写成 whistle 规则,因为规则可以被开发、测试和 CI 复用。和断言强相关的一次性数据,可以放在测试代码里,避免规则文件变成没人敢改的“黑盒”。踩坑最多的是两边都写,最后不知道哪个 Mock 生效。建议给规则文件加命名约定,例如 `e2e-login.rules`。
### HTTPS 自动化测试为什么经常失败?
最常见原因是证书没有被系统或浏览器信任,whistle 能看到请求,但页面侧直接阻断。另一个坑是某些客户端启用了证书固定,代理解密会失败,这类场景只能做旁路抓包或在测试包关闭 pinning。CI 容器里还要注意证书安装路径,不同镜像的信任库不一样。不要把 `ignoreHTTPSErrors` 当万能药,它只能让浏览器继续跑,不能证明 HTTPS 链路真的没问题。
### 如何判断 whistle 规则真的被测试用例命中了?
不要只看页面断言通过,还要检查网络侧是否经过预期域名和规则。可以在 whistle 界面查看请求,也可以让被 Mock 的响应返回测试专用字段,例如 `x-mock-source: whistle-e2e`。如果接口被浏览器缓存,规则可能根本没走,所以测试前最好禁用缓存或给请求加唯一 query。定位失败时先验证代理配置,再验证规则匹配,最后看业务断言。
### 什么时候不该把 whistle 放进自动化测试?
纯算法、纯组件渲染和后端接口契约测试,不需要 whistle,直接 mock 或启动本地服务更快。whistle 适合解决“网络路径不可控”的问题,不适合承担所有测试隔离职责。规则过多会让测试变慢,也会让新人很难理解真实请求链路。一个实用边界是:只有当问题必须在浏览器代理层复现时,才把它纳入 whistle 自动化测试。前端5月27日 21:56
whistle 代理工具有哪些应用场景?## 答案
Whistle 是基于 Node.js 的跨平台 Web 调试代理工具,通过规则文本拦截和修改 HTTP/HTTPS 请求与响应。相比直接改代码或配 hosts,核心优势是**不改代码、不切环境、规则可复用且仅对本地生效**。
前端开发中最常用的五个场景:
### 本地联调
将线上域名指向本地开发服务,省去切环境或改代码:
```bash
api.example.com host 127.0.0.1:3000
```
联调只影响你自己,其他同事访问线上不受干扰。多个后端服务可同时指向不同本地端口:
```bash
api.example.com host 127.0.0.1:3000
pay.example.com host 127.0.0.1:4000
```
需要同时联调 WebSocket 时也没问题,whistle 默认支持 ws/wss 协议代理。
### 接口 Mock
后端接口未就绪时,用本地 JSON 文件返回模拟数据:
```bash
api.example.com/user resBody://{mock-user.json}
```
在 Whistle 的 Values 面板中创建 `mock-user.json`,写入模拟响应体即可。也可以直接指定状态码:
```bash
api.example.com/error resStatus://500
```
用 `resDelay://3000` 模拟接口超时,验证前端的 loading 和兜底逻辑。需要按条件 Mock 时,用 `resScript` 编写动态逻辑:
```javascript
// timeout.js — 支付接口模拟 5 秒超时
if (rules.requestHeaders.referer && rules.requestHeaders.referer.indexOf('/pay') !== -1) {
rules.responseDelay = 5000;
rules.responseStatus = 504;
}
```
### 跨域处理
开发阶段给响应注入 CORS 头,绕过浏览器同源限制:
```bash
api.example.com resHeaders://{cors.json}
```
`cors.json` 内容示例:
```json
{
"access-control-allow-origin": "*",
"access-control-allow-methods": "GET,POST,PUT,DELETE,OPTIONS",
"access-allow-headers": "Content-Type,Authorization"
}
```
比后端加跨域配置更安全——只有你自己生效,不会影响线上环境。
### 移动端抓包与调试
手机配代理指向电脑 IP:8899,安装根证书后可捕获 HTTPS 请求:
1. 手机 Wi-Fi 设置中配置 HTTP 代理,服务器填电脑 IP,端口填 8899
2. 手机浏览器访问 `ip:8899`,下载并安装根证书
3. iOS 需在"设置 → 通用 → 关于本机 → 证书信任设置"中手动启用信任
4. Android 7+ 默认不信任用户证书,需用 `whistle.startProxy(8899, true)` 开启全局代理或 root 后安装到系统证书目录
配合内置 weinre 远程调试移动端页面 DOM 和控制台:
```bash
m.example.com weinre://debug
```
也可以安装 `whistle.inspect` 插件注入 vConsole/Eruda,在 App 内直接查看调试面板:
```bash
npm i -g whistle.inspect
m.example.com whistle.inspect://vconsole
```
### 异常场景模拟
用规则快速构造边界条件,测试前端兜底逻辑:
```bash
# 模拟接口延迟 3 秒
api.example.com/api resDelay://3000
# 模拟 500 错误
api.example.com/api resStatus://500
# 模拟弱网(限速 30kb/s)
api.example.com/api reqSpeed://30
```
复杂条件用 `resScript` 处理,简单场景一条规则就够。
### 规则管理建议
- 用 `# 注释` 标记每条规则的用途,方便团队协作
- JSON 数据统一放在 Values 面板管理,别直接内联在规则里
- 调试完及时关闭代理并移除证书,防止隐私泄露和证书风险
- 善用 `ignore://*` 跳过不需要代理的请求,减少干扰
## 追问
- **whistle 和 Charles/Fiddler 的区别?** —— whistle 免费开源、基于规则文本配置(可版本管理)、支持 Node 插件扩展;Charles/Fiddler 偏 GUI 操作,Charles 收费且仅 macOS/Windows,Fiddler 仅 Windows。whistle 天然跨平台且规则可团队共享。
- **如何让 whistle 代理 HTTPS 请求?** —— 需要安装并信任 whistle 的根证书:在 Whistle 界面点击 HTTPS → 安装根证书,桌面端安装到系统钥匙串/iOS 信任设置中并启用信任,Android 7+ 用户证书默认不被信任需特殊处理。浏览器和系统层面都需要配置信任。
- **SwitchyOmega 和 whistle 是什么关系?** —— SwitchyOmega 是浏览器代理切换插件,负责把浏览器流量导向 whistle 所在的地址和端口;whistle 负责具体的规则匹配和请求处理。两者配合:SwitchyOmega 控制哪些流量走代理,whistle 决定代理后怎么处理。
- **whistle 规则的优先级是什么?** —— 默认从上到下匹配,先匹配到的规则优先。可用 `enable://proxyFirst` 改为代理优先模式。`ignore://` 规则会跳过所有其他规则,优先级最高。同名规则后写的会覆盖前面的。
- **whistle 插件有什么用?** —— 通过 Node 模块扩展功能,如 `whistle.inspect` 注入 vConsole/Eruda、`whistle.vase` 做接口录制回放、`whistle.autocoder` 自动生成规则。安装后 `w2 restart` 即可使用。前端5月27日 21:46
whistle 如何支持 WebSocket 代理和调试?## 核心答案
Whistle 基于代理机制自动拦截 WebSocket 连接,在 Network 面板的 Frames 标签中实时展示收发消息,配合规则可以实现暂停、忽略、Mock 等调试操作。
具体分三步:
**1. 抓包查看消息**
设置代理后,Whistle 自动捕获 ws/wss 请求。在 Network 面板选中该请求,切换到 Frames 标签即可看到实时消息流,JSON 消息会自动格式化。
**2. 用规则控制连接行为**
```
# 暂停接收服务端消息
ws://example.com enable://pauseReceive
# 暂停发送客户端消息
ws://example.com enable://pauseSend
# 忽略收发(不转发)
ws://example.com enable://ignoreReceive
ws://example.com enable://ignoreSend
```
**3. 用 Composer 构造和发送消息**
在 Frames 面板底部有 Composer 区域,可以直接向服务端或客户端发送自定义文本/JSON 数据,用于模拟服务端推送或异常响应。
## 追问一:如何修改 WebSocket 消息内容?
Whistle 原生不支持直接改写 WebSocket 消息体,需要借助 `frameScript` 规则或插件:
- **frameScript**:在 Rules 面板配置 `ws://example.com frameScript://{wsModify.js}`,脚本中监听 `onframe` 事件对帧数据做替换
- **插件方式**:安装 `whistle.script` 插件,配置 `ws://example.com script://handleWS`,在脚本中拦截并修改 message
## 追问二:Whistle 如何处理 wss 连接?
和 HTTPS 一样需要安装 Whistle 的根证书。证书装好后,Whistle 通过 MITM 方式解密 wss 流量,抓包和调试方式与 ws 完全一致。
## 追问三:如何 Mock WebSocket 服务端?
用 Composer 手动发消息是最快的方式。如需自动化,可以写插件监听 `upgrade` 事件,在 `server.on('connection')` 回调中按业务逻辑返回 Mock 数据,配置规则指向该插件即可。前端5月27日 21:43
whistle 和 Charles 有什么区别,如何选择使用?## 核心结论
Whistle 开源免费、规则灵活、扩展性强,适合日常高频调试的前端开发者;Charles 图形界面友好、开箱即用,适合偶尔抓包或不熟悉命令行的用户。两者都是 HTTP/HTTPS 调试代理,但设计理念不同:Whistle 靠规则配置驱动,Charles 靠可视化操作驱动。
## 关键差异
| 维度 | Whistle | Charles |
|------|---------|---------|
| 开源与费用 | 完全开源免费 | 商业软件,$50/许可证 |
| 技术栈 | Node.js,npm 安装 | Java,独立安装包 |
| 配置方式 | 规则语法(类似 hosts),可脚本化 | 图形界面点选操作 |
| 协议支持 | HTTP/HTTPS/WebSocket/TCP | HTTP/HTTPS |
| 插件生态 | npm 插件,可注入 JS/CSS/vConsole | 内置功能为主,扩展有限 |
| 移动端抓包 | 需手动配代理+装证书,规则可共享 | 同样需配代理,界面操作更直观 |
| Mock 能力 | 规则指定接口固定返回,不会超时 | Map Local/Rewrite 实现,配置稍繁琐 |
## 选 Whistle 的典型场景
- **团队协作**:规则文件可纳入 Git 版本控制,新人拉取即用
- **频繁 Mock**:前端联调时给接口固定回参,避免后端未就绪导致阻塞
- **注入调试**:通过插件往页面注入 vConsole、eruda 等移动端调试工具
- **预算有限**:个人项目或小团队不想付费
## 选 Charles 的典型场景
- **临时抓包**:偶尔排查一个接口问题,打开就能用
- **带宽限速测试**:内置 Throttle 功能,模拟弱网环境更方便
- **AJAX 调试**:请求/响应结构化展示清晰,搜索匹配可定位到具体字段
- **非技术背景**:产品或测试人员更习惯图形界面
## 追问:能不能两个都用?
可以。日常开发用 Whistle 处理规则和 Mock,遇到需要弱网测试或快速排查时切 Charles。注意两者不能同时监听同一端口,需错开代理端口配置。前端5月27日 21:43
whistle 常见问题有哪些,如何排查和解决?## 核心排查思路
Whistle 常见问题集中在四个环节:**安装启动 → 代理连通 → HTTPS 证书 → 规则生效**。逐层排查即可定位大多数问题。
## 安装启动失败怎么办
安装报 `EACCES` 权限错误,用 `sudo npm i -g whistle` 或改用 nvm 管理 Node 版本。启动报端口占用,先 `w2 stop` 再 `w2 start`,或用 `-p` 指定端口:`w2 start -p 8080`。启动成功但无法访问 `127.0.0.1:8899`,运行 `w2 status` 确认进程存活,再检查防火墙是否放行了对应端口。
## 手机连不上代理怎么排查
确保手机和电脑在同一 Wi-Fi 下,手机代理地址填电脑局域网 IP(不是 127.0.0.1),端口填 whistle 监听端口。电脑防火墙需允许该端口入站连接。仍不通时,用 `curl -x http://电脑IP:端口 http://example.com` 在另一设备验证代理是否可达。
## HTTPS 抓包失败如何解决
这是最高频问题,分两步走:
1. **启用 HTTPS 拦截**:whistle 面板点击 HTTPS → 勾选 Capture HTTPS
2. **安装根证书**:浏览器访问 `rootca.pro` 下载证书,安装到系统"受信任的根证书颁发机构"
iOS 额外步骤:安装描述文件后,还需在"设置 → 通用 → 关于本机 → 证书信任设置"中手动开启信任。Android 7+ 默认不信任用户证书,需 root 或配置 network_security_config。Firefox 使用独立证书库,需单独导入。
## 规则不生效怎么排查
按以下顺序检查:规则语法是否正确 → 是否被注释或被更靠前的规则覆盖 → 是否需要 `w2 restart` 重载 → 浏览器缓存是否干扰(用隐身模式验证)。在 Network 面板查看请求是否经 whistle 转发,未转发则代理配置有误。
## 性能问题如何优化
规则过多或正则过复杂会拖慢响应。精简规则、避免贪婪匹配,必要时 `w2 restart` 释放内存。日志积累过多时清空:Network → Tools → Server 清理即可。
> 追问:应用使用了 SSL Pinning 怎么办?— 用 `域名 disable://capture` 跳过该域名的解密,或借助 Frida/Xposed 绕过证书校验。多实例共存?用不同端口和 `--dirname` 指定独立数据目录启动。前端5月27日 21:38
whistle 的规则语法是什么,常用的操作符有哪些?## 规则语法
Whistle 规则的基本格式为 `pattern operation [lineProps] [filters]`,即"匹配模式 + 操作 + 可选配置"。
当请求 URL 匹配 pattern 时,whistle 对其执行 operation 定义的操作。
## 常用操作符
**修改请求/响应:**
- `reqHeaders`:修改请求头,如 `www.test.com reqHeaders://x-token=abc`
- `resHeaders`:修改响应头,如 `www.test.com resHeaders://{cors.json}`
- `resBody` / `resReplace`:替换响应体或响应内容
**映射与代理:**
- `file`:映射到本地文件,如 `www.test.com/api file://{mock.json}`
- `host`:修改 Host 指向,如 `www.test.com host 127.0.0.1:8080`
- `proxy` / `forward`:通过代理或指定地址转发请求
**脚本与延迟:**
- `reqScript` / `resScript`:用脚本动态处理请求或响应
- `resDelay`:模拟响应延迟,如 `www.test.com resDelay://3000`
## 匹配模式
按模糊程度从精确到宽泛:
1. **精确匹配**:`$www.test.com/api` — 加 `$` 前缀,仅匹配该 URL
2. **路径匹配**:`www.test.com/api` — 匹配该路径下所有请求
3. **通配符匹配**:`*.test.com` 或 `^https://**.test.com/**`
4. **正则匹配**:`/api\/v2/i` — 用正则灵活匹配 URL
## 规则优先级与合并
- 相同 pattern 不同 operation 会合并生效,如 `www.test.com resDelay://3000 file://{data.json}` 同时延迟并返回本地数据
- 相同 pattern 相同 operation 取最前面的规则
- 用 `lineProps://important` 提升单行优先级
- 用 `excludeFilter` / `includeFilter` 对匹配结果二次过滤
## 追问
- Whistle 如何实现只对 POST 请求生效?用 `includeFilter://m:post` 过滤请求方法
- 多条规则冲突时如何排查?看 Rules 面板的匹配日志,或用 `lineProps://important` 调整优先级
- Whistle 和 Charles 的核心区别?Whistle 基于规则文件配置、支持脚本和插件,Charles 偏 GUI 操作前端5月27日 21:36
whistle 如何进行性能监控和分析,有哪些优化建议?## 答案
Whistle 的性能监控和分析主要依赖 Network 面板和规则配置,核心思路是:**抓包看耗时,规则模拟瓶颈,对比验证优化效果。**
### Network 面板分析请求耗时
Whistle 的 Network 面板类似 Chrome DevTools,展示所有经过代理的 HTTP/HTTPS 请求。选中某条请求后,右侧详情面板可查看请求头、响应头、Cookie、耗时等完整信息。通过点击 Timeline 列可切换为时间线视图,直观看到每个请求的起止时间和并发关系,快速定位慢请求。
实际操作中,先按耗时排序找出 Top 慢请求,再逐个分析是 DNS 解析慢、服务端响应慢(TTFB 高),还是资源体积大导致下载慢,针对性优化。
### 弱网模拟测试性能下限
用 `reqDelay` 和 `reqSpeed` 规则模拟弱网:
```
# 延迟 3 秒
www.example.com reqDelay://3000
# 限速 50kb/s
www.example.com reqSpeed://50
```
移动端场景必须做弱网测试。Whistle 的优势在于手机配代理后直接生效,比 Chrome DevTools 的弱网模拟更贴近真实移动环境。
### 规则辅助性能优化验证
**压缩验证**:用 `enable://gzip` 或 `enable://br` 强制开启压缩,对比响应体积变化:
```
www.example.com enable://gzip
```
**缓存测试**:用 `cache://` 规则控制缓存策略,验证缓存头是否生效:
```
www.example.com/static cache://86400
www.example.com/api cache://no-store
```
**资源替换**:用 `resReplace` 替换线上资源为本地优化版本,快速验证优化效果:
```
www.example.com resReplace://old.js local-optimized.js
```
### 实战优化流程
1. 用 Network 面板抓包,按耗时排序找瓶颈
2. 弱网模拟验证最差体验
3. 规则注入压缩/缓存/替换,对比优化前后数据
4. 用 Composer 重放请求,确认优化稳定
Whistle 不是性能监控平台,而是**开发阶段的性能诊断工具**,适合在上线前发现和验证问题,线上监控仍需 RUM 方案。
### 追问
**Q: Whistle 和 Chrome DevTools 的 Network 面板有什么区别?**
Whistle 是独立代理,能抓取手机 App、小程序等非浏览器场景的请求,这是浏览器内嵌工具做不到的。
**Q: 如何用 Whistle 持续监控性能?**
Whistle 本身不支持持续监控,但可以导出 HAR 文件,结合脚本定期采集后做趋势分析。前端5月27日 21:34
whistle 如何解决跨域问题,有哪些常见的跨域场景?## 答案
Whistle 通过 `resCors` 协议一行规则即可解决跨域,无需手写脚本或配置 JSON 文件。
**最常用的三种写法:**
```
# 允许所有源(开发环境推荐)
api.example.com resCors://*
# 仅允许指定源
api.example.com resCors://https://www.myapp.com
# 启用 CORS 并自动回显请求中的 Origin
api.example.com resCors://enable
```
`resCors://enable` 会把响应头 `Access-Control-Allow-Origin` 设为请求携带的 Origin 值,适合需要携带 Cookie 的场景。`resCors://*` 直接设置 `Access-Control-Allow-Origin: *`,浏览器不会发送凭证但足够覆盖大多数调试需求。
如果需要额外控制允许的方法或头部,用 `resHeaders` 补充:
```
api.example.com resCors://* resHeaders://{cors-extra.json}
```
另一种思路是代理到同源:通过 whistle 将前端和 API 映射到同一域名下,从根源消除跨域:
```
my.app.com/api api.example.com
my.app.com 127.0.0.1:3000
```
## 常见跨域场景
**本地调试:** 前端跑在 `localhost:3000`,后端在 `api.example.com`,加一条 `resCors://*` 即可。
**多子域名:** `www.example.com` 访问 `api.example.com`,用 `resCors://https://www.example.com` 限定来源。
**携带凭证:** 需要带 Cookie 时必须指定具体源,用 `resCors://enable` 或 `resCors://https://www.myapp.com`,不能使用 `*`。
**线上排查:** 结合 SwitchyOmega 将流量导到 whistle,用 `resCors://enable` 临时放开,抓完即关。
## 追问
- **resCors 和 resHeaders 手动加 CORS 头有什么区别?** `resCors` 是 whistle 内置协议,会同时处理预检请求(OPTIONS)的响应;手动加头容易遗漏 `Access-Control-Max-Age` 等字段,导致频繁预检。
- **生产环境能用 whistle 解决跨域吗?** 不能。whistle 是开发调试工具,生产环境应由 Nginx 或后端服务配置 CORS 策略。
- **Cookie 跨域为什么不能用 `*`?** 浏览器规范要求 `Access-Control-Allow-Credentials: true` 时 Origin 不能为 `*`,否则请求直接失败。前端5月27日 21:33
whistle 常用的命令行操作有哪些?## 核心命令
Whistle 的命令行操作都通过 `w2` 命令完成,常用命令如下:
- `w2 start` — 启动服务,默认监听 8899 端口
- `w2 start -p 8080` — 指定端口启动
- `w2 start -S storageName` — 指定存储目录,用于多实例管理
- `w2 start -n user -w pass` — 设置管理界面的登录用户名和密码
- `w2 stop` — 停止服务
- `w2 restart` — 重启服务
- `w2 status` — 查看运行状态
- `w2 proxy` — 设置系统代理
- `w2 proxy 0` — 关闭系统代理
- `w2 ca` — 安装 HTTPS 根证书(抓 HTTPS 请求必须)
- `w2 -h` — 查看帮助
安装只需 `npm i -g whistle`,Mac 用户也可用 `brew install whistle`。
## 多实例管理
需要同时运行多个 whistle 实例时,每个实例必须指定独立的端口和存储目录:
```bash
w2 start -p 8010 -S 8010
w2 start -p 8020 -S 8020
```
建议端口和存储目录使用相同编号,便于管理。
## 启动进阶参数
- `--httpsPort 8001` — 启用 HTTPS 代理端口
- `--socksPort 1080` — 启用 SOCKSv5 代理端口
- `-P 8889` — 单独设置管理界面端口
- `--inspect` — 开启 Node.js 调试(默认 9229 端口)
- `--config /path/to/config.json` — 从配置文件加载参数
## 追问:如何在命令行快速切换代理环境?
通过 `-S` 指定不同存储目录,每个目录维护独立的规则集。脚本化切换:
```bash
#!/bin/bash
w2 stop
w2 start -p 8899 -S $1
```
执行 `./switch.sh dev` 即可切换到 dev 环境的规则,无需手动编辑配置。前端5月27日 21:30
如何使用 whistle 拦截 HTTPS 请求,证书如何配置?## 答案
whistle 作为本地代理,对 HTTPS 请求执行中间人解密:收到客户端 CONNECT 后,用自签 RootCA 为目标域名动态签发证书,再以该证书与客户端建立 TLS 连接,明文拿到请求内容后转发给真实服务器。要让客户端信任这些动态证书,必须把 whistle 的 RootCA 装进系统或浏览器的信任链。
## 证书配置
1. 启动并打开管理界面
```bash
npm i -g whistle && w2 start
```
浏览器访问 `http://127.0.0.1:8899`。
2. 下载根证书
管理界面点击 HTTPS 标签,下载 RootCA。
3. 安装到系统信任链
- **Mac**:钥匙串访问 → 导入 → 双击设为"始终信任"
- **Windows**:双击证书 → 安装到"本地计算机" → 放入"受信任的根证书颁发机构"
- **Linux**:`sudo cp rootCA.crt /usr/local/share/ca-certificates/ && sudo update-ca-certificates`
4. 开启拦截
勾选 HTTPS 面板的 "Capture HTTPS CONNECTs";只想拦截特定域名用规则 `example.com filter://intercept`。
## 移动端
手机连同一 Wi-Fi,浏览器访问 `http://rootca.pro` 下载证书,系统设置中信任该证书,再将手机代理指向电脑 IP:8899。
## 踩坑点
- **Android 7+**:应用默认不信任用户证书,需 root 或配置 network_security_config
- **iOS 10.3+**:安装后还得到 设置 → 通用 → 关于本机 → 证书信任设置 手动开启
- **Firefox**:独立证书库,需在 about:preferences 单独导入 RootCA
- **证书锁定**:部分 App 校验服务器证书指纹,代理无法拦截
## 追问
- whistle 拦截 HTTPS 的原理?——中间人代理 + 动态签发证书
- 如何只拦截特定域名?——`filter://intercept` 规则
- Android 高版本为什么抓不到包?——用户证书信任域变更