Whistle
Whistle Proxy 是一个开源的网络调试代理工具,主要用于捕获和修改 HTTP(S) 网络请求。它支持多种平台,包括 Windows、Mac 和 Linux。Whistle Proxy 常被用于前端开发和测试中,以调试和优化应用程序的网络请求。

查看更多相关内容
whistle 如何支持 WebSocket 代理和调试?## 答案
Whistle 提供了 WebSocket 代理功能,可以捕获、调试和修改 WebSocket 连接和消息。
### WebSocket 代理基础
#### 1. 基本 WebSocket 代理
**配置规则:**
```
ws://example.com host 127.0.0.1:8080
wss://example.com host 127.0.0.1:8080
```
**或者使用 forward 操作符:**
```
ws://example.com forward ws://127.0.0.1:8080
wss://example.com forward wss://127.0.0.1:8080
```
#### 2. WebSocket 消息捕获
Whistle 会自动捕获 WebSocket 连接和消息:
- **连接建立**:记录 WebSocket 握手信息
- **消息发送**:记录客户端发送的消息
- **消息接收**:记录服务器返回的消息
- **连接关闭**:记录连接关闭原因
### WebSocket 调试功能
#### 1. 查看消息详情
在 whistle 管理界面中:
1. 点击 "Network" 标签
2. 筛选 "WS" 类型的请求
3. 点击 WebSocket 连接查看详情
4. 查看 "Messages" 标签中的消息历史
#### 2. 消息格式化
Whistle 会自动格式化 JSON 消息:
```json
{
"type": "message",
"data": {
"id": 1,
"content": "Hello"
}
}
```
#### 3. 消息过滤
可以使用过滤器快速查找特定消息:
- 按消息类型过滤
- 按消息内容搜索
- 按时间范围过滤
### WebSocket 消息修改
#### 1. 使用插件修改消息
**创建插件:`websocket-modifier.js`**
```javascript
module.exports = function(server, options) {
server.on('upgrade', function(req, socket, head) {
console.log('WebSocket upgrade:', req.url);
});
server.on('connection', function(ws, req) {
ws.on('message', function(message) {
console.log('Received message:', message.toString());
// 修改消息
const modifiedMessage = modifyMessage(message);
ws.send(modifiedMessage);
});
});
};
function modifyMessage(message) {
const data = JSON.parse(message.toString());
data.timestamp = Date.now();
return JSON.stringify(data);
}
```
**配置规则:**
```
ws://example.com plugin://websocket-modifier
```
#### 2. 拦截和修改握手
**创建脚本:`websocket-handshake.js`**
```javascript
module.exports = function(req, res) {
// 修改 WebSocket 握手头
if (req.headers['upgrade'] === 'websocket') {
req.headers['X-Custom-Header'] = 'Custom Value';
}
};
```
**配置规则:**
```
ws://example.com reqScript://{websocket-handshake.js}
```
### WebSocket 性能监控
#### 1. 连接时间监控
Whistle 会记录 WebSocket 连接的各个阶段时间:
- **DNS 解析时间**
- **TCP 连接时间**
- **SSL/TLS 握手时间**(对于 wss)
- **连接建立时间**
#### 2. 消息统计
- **消息数量**:发送和接收的消息总数
- **消息大小**:消息的平均大小和总大小
- **消息频率**:消息发送和接收的频率
#### 3. 连接状态监控
- **连接状态**:连接是否活跃
- **连接时长**:连接持续时间
- **重连次数**:连接重连的次数
### WebSocket 调试技巧
#### 1. 模拟服务器响应
**创建脚本:`websocket-mock.js`**
```javascript
module.exports = function(server, options) {
server.on('upgrade', function(req, socket, head) {
console.log('Mock WebSocket server');
// 模拟服务器行为
socket.on('data', function(data) {
console.log('Client message:', data.toString());
// 返回模拟响应
const response = JSON.stringify({
type: 'response',
data: 'Mock response',
timestamp: Date.now()
});
socket.write(response);
});
});
};
```
#### 2. 消息延迟模拟
**创建脚本:`websocket-delay.js`**
```javascript
module.exports = function(server, options) {
server.on('connection', function(ws, req) {
ws.on('message', function(message) {
// 模拟延迟
setTimeout(() => {
ws.send(message);
}, 1000); // 延迟 1 秒
});
});
};
```
#### 3. 消息丢失模拟
**创建脚本:`websocket-drop.js`**
```javascript
module.exports = function(server, options) {
let messageCount = 0;
server.on('connection', function(ws, req) {
ws.on('message', function(message) {
messageCount++;
// 每 10 条消息丢弃 1 条
if (messageCount % 10 !== 0) {
ws.send(message);
} else {
console.log('Dropped message:', messageCount);
}
});
});
};
```
### 常见问题解决
#### 1. WebSocket 连接失败
**检查项:**
- 确认代理规则正确
- 检查目标服务器是否支持 WebSocket
- 确认防火墙设置
- 检查 SSL 证书(对于 wss)
#### 2. 消息乱码
**解决方法:**
- 确认消息编码格式
- 检查消息是否为二进制数据
- 使用正确的解码方式
#### 3. 连接频繁断开
**原因:**
- 网络不稳定
- 服务器超时设置
- 心跳机制问题
**解决方法:**
- 增加超时时间
- 实现心跳机制
- 优化网络环境
### 最佳实践
1. **使用插件进行复杂处理**
- 插件提供更强大的功能
- 便于复用和维护
2. **记录消息日志**
- 便于问题排查
- 分析消息模式
3. **测试异常场景**
- 测试网络中断
- 测试消息丢失
- 测试连接超时
4. **性能优化**
- 减少不必要的消息处理
- 使用消息压缩
- 优化消息格式
前端 · 2月21日 16:27
whistle 在实际开发中有哪些应用场景和实战技巧?## 答案
Whistle 在实际开发中有许多实用的应用场景,可以大大提高开发效率和问题排查能力。
### 常见应用场景
#### 1. 本地开发调试
**场景描述:**
前端开发时需要调用后端接口,但后端服务在本地运行,需要将线上域名指向本地服务。
**解决方案:**
```
# 将线上域名指向本地服务
www.example.com host 127.0.0.1:3000
api.example.com host 127.0.0.1:3001
# 或者使用 forward 操作符
www.example.com forward http://127.0.0.1:3000
```
**优点:**
- 无需修改代码中的域名
- 快速切换本地和线上环境
- 便于前后端联调
#### 2. 解决跨域问题
**场景描述:**
前端开发时遇到跨域问题,需要添加 CORS 响应头。
**解决方案:**
```
# 添加 CORS 响应头
www.example.com resHeaders://{cors-headers.json}
```
**cors-headers.json:**
```json
{
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization"
}
```
**优点:**
- 无需后端修改代码
- 快速解决跨域问题
- 适合开发环境使用
#### 3. 接口数据模拟
**场景描述:**
后端接口尚未开发完成,前端需要先开发功能,需要模拟接口返回数据。
**解决方案:**
```
# 模拟用户接口
www.example.com/api/user resBody://{mock-user.json}
# 模拟列表接口
www.example.com/api/list resBody://{mock-list.json}
# 使用脚本动态生成数据
www.example.com/api/dynamic resScript://{dynamic-mock.js}
```
**mock-user.json:**
```json
{
"code": 0,
"data": {
"id": 1,
"name": "张三",
"age": 25
}
}
```
**优点:**
- 前后端并行开发
- 提高开发效率
- 便于测试各种场景
#### 4. 多环境切换
**场景描述:**
需要在开发、测试、生产环境之间快速切换,测试不同环境的功能。
**解决方案:**
**创建不同环境的配置文件:**
**rules-dev:**
```
www.example.com host 127.0.0.1:3000
api.example.com host 127.0.0.1:3001
```
**rules-test:**
```
www.example.com host test.example.com
api.example.com host api-test.example.com
```
**rules-prod:**
```
www.example.com host prod.example.com
api.example.com host api-prod.example.com
```
**切换环境:**
```bash
# 切换到开发环境
w2 restart -f rules-dev
# 切换到测试环境
w2 restart -f rules-test
# 切换到生产环境
w2 restart -f rules-prod
```
**优点:**
- 快速切换环境
- 避免修改代码
- 提高测试效率
#### 5. 性能优化测试
**场景描述:**
需要测试网站性能,找出性能瓶颈。
**解决方案:**
```
# 启用 gzip 压缩
www.example.com resHeaders://{compression-headers.json}
# 设置缓存策略
www.example.com/static/* resHeaders://{cache-headers.json}
# 模拟慢速网络
www.example.com resScript://{slow-network.js}
```
**slow-network.js:**
```javascript
module.exports = function(req, res) {
setTimeout(() => {
res.end(JSON.stringify({ code: 0, data: 'success' }));
}, 2000); // 延迟2秒
};
```
**优点:**
- 模拟真实网络环境
- 发现性能问题
- 优化用户体验
#### 6. 移动端调试
**场景描述:**
需要在移动设备上调试 Web 应用或混合应用。
**解决方案:**
1. **配置手机代理**
- 手机和电脑连接同一 Wi-Fi
- 配置手机代理指向电脑 IP 和 whistle 端口
- 安装 HTTPS 证书
2. **添加移动端专用规则**
```
# 移动端接口模拟
m.example.com/api/user resBody://{mobile-mock-user.json}
# 移动端跨域处理
m.example.com resHeaders://{cors-headers.json}
```
**优点:**
- 真实设备测试
- 捕获移动端网络请求
- 解决移动端特定问题
#### 7. 接口错误模拟
**场景描述:**
需要测试应用对各种错误情况的处理,如网络错误、服务器错误等。
**解决方案:**
```
# 模拟 500 错误
www.example.com/api/error resBody://{"code":500,"message":"服务器错误"}
# 模拟超时
www.example.com/api/timeout resScript://{timeout.js}
# 模拟网络错误
www.example.com/api/network-error resScript://{network-error.js}
```
**timeout.js:**
```javascript
module.exports = function(req, res) {
// 不返回响应,模拟超时
setTimeout(() => {
// 可选:返回超时错误
res.statusCode = 408;
res.end(JSON.stringify({ code: 408, message: '请求超时' }));
}, 30000);
};
```
**优点:**
- 测试异常处理逻辑
- 提高应用健壮性
- 便于排查问题
#### 8. 接口数据修改
**场景描述:**
需要修改接口返回的数据,测试不同数据场景。
**解决方案:**
```
# 修改响应数据
www.example.com/api/user resScript://{modify-data.js}
# 替换响应内容
www.example.com resReplace://old-string/new-string
```
**modify-data.js:**
```javascript
module.exports = function(req, res) {
const originalEnd = res.end;
res.end = function(chunk, encoding) {
if (chunk) {
const body = chunk.toString();
const jsonData = JSON.parse(body);
// 修改数据
jsonData.data.status = 'active';
jsonData.data.timestamp = Date.now();
originalEnd.call(res, JSON.stringify(jsonData), encoding);
} else {
originalEnd.call(res, chunk, encoding);
}
};
};
```
**优点:**
- 快速测试不同数据场景
- 无需后端修改
- 提高测试效率
#### 9. 接口请求修改
**场景描述:**
需要修改请求参数或请求头,测试不同请求场景。
**解决方案:**
```
# 修改请求头
www.example.com reqHeaders://{custom-headers.json}
# 使用脚本修改请求
www.example.com reqScript://{modify-request.js}
```
**custom-headers.json:**
```json
{
"X-Custom-Header": "Custom Value",
"X-Request-ID": "12345"
}
```
**modify-request.js:**
```javascript
module.exports = function(req, res) {
// 添加请求参数
if (req.url.includes('/api/user')) {
const separator = req.url.includes('?') ? '&' : '?';
req.url += separator + 'debug=true';
}
// 修改请求头
req.headers['X-Debug-Mode'] = 'true';
};
```
**优点:**
- 测试不同请求场景
- 添加调试信息
- 便于问题排查
#### 10. WebSocket 调试
**场景描述:**
需要调试 WebSocket 连接和消息。
**解决方案:**
```
# WebSocket 代理
ws.example.com host 127.0.0.1:8080
# 使用插件调试 WebSocket
ws.example.com plugin://websocket-debugger
```
**优点:**
- 捕获 WebSocket 消息
- 调试实时通信
- 解决连接问题
### 实战技巧
#### 1. 规则分组管理
使用注释和分组来管理大量规则:
```
# ==================== 本地开发 ====================
www.local.com host 127.0.0.1:3000
api.local.com host 127.0.0.1:3001
# ==================== 测试环境 ====================
www.test.com host test.example.com
api.test.com host api-test.example.com
# ==================== 数据模拟 ====================
www.example.com/api/user resBody://{mock-user.json}
www.example.com/api/list resBody://{mock-list.json}
```
#### 2. 快速启用/禁用规则
在规则前添加 `#` 来快速禁用规则:
```
# www.example.com host 127.0.0.1:3000 # 禁用
www.example.com host test.example.com # 启用
```
#### 3. 使用 Values 文件
创建 Values 文件存储常用配置:
**values.json:**
```json
{
"local-ip": "127.0.0.1",
"local-port": "3000",
"test-host": "test.example.com"
}
```
**在规则中使用:**
```
www.example.com host {{local-ip}}:{{local-port}}
```
#### 4. 导出和导入配置
定期导出配置文件,便于备份和分享:
```bash
# 导出配置
cp ~/.whistle/rules ~/backup/whistle-rules-$(date +%Y%m%d)
# 导入配置
cp ~/backup/whistle-rules-20240101 ~/.whistle/rules
```
### 最佳实践
1. **定期备份配置**
- 避免配置丢失
- 便于回滚
2. **使用版本控制**
- 使用 Git 管理配置文件
- 便于团队协作
3. **添加清晰注释**
- 说明规则用途
- 便于维护
4. **定期清理规则**
- 删除不再使用的规则
- 保持配置简洁
5. **安全考虑**
- 不要在公共网络使用
- 调试完成后关闭代理
- 保护证书安全
前端 · 2月21日 16:27
whistle 常见问题有哪些,如何排查和解决?## 答案
Whistle 在实际使用中可能会遇到各种问题,了解常见问题及其解决方法可以提高工作效率。
### 安装和启动问题
#### 1. 安装失败
**问题:**
```bash
npm install -g whistle
# 报错:EACCES: permission denied
```
**解决方法:**
**方法一:使用 sudo(Mac/Linux)**
```bash
sudo npm install -g whistle
```
**方法二:修改 npm 目录权限**
```bash
sudo chown -R $(whoami) ~/.npm
sudo chown -R $(whoami) /usr/local/lib/node_modules
```
**方法三:使用 nvm**
```bash
nvm install node
nvm use node
npm install -g whistle
```
#### 2. 启动失败
**问题:**
```bash
w2 start
# 报错:Port 8899 is already in use
```
**解决方法:**
**方法一:查找并关闭占用端口的进程**
```bash
# Mac/Linux
lsof -i :8899
kill -9 <PID>
# Windows
netstat -ano | findstr :8899
taskkill /PID <PID> /F
```
**方法二:使用其他端口**
```bash
w2 start -p 8080
```
**方法三:停止之前的 whistle 实例**
```bash
w2 stop
w2 start
```
#### 3. 启动后无法访问
**问题:**
启动成功但无法访问 `http://127.0.0.1:8899/`
**解决方法:**
**检查 whistle 是否正在运行:**
```bash
w2 status
```
**检查防火墙设置:**
- Windows:允许 whistle 通过防火墙
- Mac:系统偏好设置 → 安全性与隐私 → 防火墙
- Linux:检查 iptables 或 ufw 设置
**检查端口是否正确:**
```bash
# 查看监听端口
netstat -an | grep 8899
```
### 配置问题
#### 1. 规则不生效
**问题:**
配置了规则但没有生效
**解决方法:**
**检查规则语法:**
- 确保规则格式正确
- 检查是否有语法错误
- 查看规则是否被注释
**检查规则优先级:**
- 更具体的规则应该放在前面
- 检查是否有规则冲突
**重启 whistle:**
```bash
w2 restart
```
**清除浏览器缓存:**
- 清除浏览器缓存和 Cookie
- 使用隐私模式测试
#### 2. HTTPS 拦截失败
**问题:**
无法拦截 HTTPS 请求
**解决方法:**
**检查 HTTPS 拦截是否启用:**
1. 访问 `http://127.0.0.1:8899/`
2. 点击 "HTTPS" 标签
3. 勾选 "Capture HTTPS"
**检查证书是否正确安装:**
- 下载根证书
- 安装到受信任的根证书颁发机构
- 重启浏览器
**使用规则启用 HTTPS:**
```
pattern whistle.https://
```
#### 3. 代理配置错误
**问题:**
浏览器无法通过 whistle 代理访问网络
**解决方法:**
**检查代理配置:**
- 确认代理地址正确:`127.0.0.1:8899`
- 确认代理类型:HTTP 代理
- 确认没有配置 PAC 文件
**测试代理连接:**
```bash
curl -x http://127.0.0.1:8899 http://www.example.com
```
**检查网络连接:**
- 确认电脑可以访问网络
- 检查 DNS 设置
### 性能问题
#### 1. whistle 运行缓慢
**问题:**
whistle 响应缓慢,影响开发效率
**解决方法:**
**清除缓存:**
```bash
w2 clean cache
```
**减少规则数量:**
- 删除不必要的规则
- 使用更精确的匹配模式
**增加内存限制:**
```bash
node --max-old-space-size=4096 $(which w2) start
```
**升级到最新版本:**
```bash
npm update -g whistle
```
#### 2. 内存占用过高
**问题:**
whistle 占用大量内存
**解决方法:**
**查看内存使用:**
```bash
w2 memory
```
**限制日志大小:**
```bash
w2 log clear
```
**定期重启 whistle:**
```bash
w2 restart
```
**优化规则:**
- 避免使用复杂的正则表达式
- 减少脚本处理
#### 3. CPU 占用过高
**问题:**
whistle 占用大量 CPU
**解决方法:**
**查看 CPU 使用:**
```bash
w2 cpu
```
**检查插件:**
- 禁用不必要的插件
- 更新插件到最新版本
**优化脚本:**
- 减少脚本中的复杂计算
- 使用异步操作
### 移动端问题
#### 1. 手机无法连接到代理
**问题:**
配置了手机代理但无法连接
**解决方法:**
**检查网络连接:**
- 确认手机和电脑在同一 Wi-Fi
- 测试手机能否访问电脑 IP
**检查代理配置:**
- 确认代理地址是电脑 IP
- 确认代理端口是 8899
- 确认代理类型是 HTTP
**检查防火墙:**
- 允许 whistle 通过防火墙
- 允许 8899 端口入站连接
#### 2. HTTPS 证书安装失败
**问题:**
手机无法安装或信任 HTTPS 证书
**解决方法:**
**iOS 设备:**
1. 下载证书后打开"设置" → "已下载描述文件"
2. 安装证书
3. 进入"设置" → "通用" → "关于本机" → "证书信任设置"
4. 启用"完全信任"
**Android 设备:**
1. 下载证书后打开
2. 按照提示安装
3. 进入"设置" → "安全" → "加密与凭据" → "受信任的凭据"
4. 确认证书已安装
**重启手机浏览器**
#### 3. 某些应用无法拦截
**问题:**
某些应用的请求无法被 whistle 拦截
**解决方法:**
**检查应用是否使用系统代理:**
- 某些应用不使用系统代理
- 需要使用 VPN 模式
**检查证书绑定:**
- 某些应用使用证书绑定
- 需要使用 Frida 等工具
**检查网络库:**
- 某些应用使用自定义网络库
- 需要逆向分析
### WebSocket 问题
#### 1. WebSocket 连接失败
**问题:**
WebSocket 无法建立连接
**解决方法:**
**检查代理规则:**
```
ws://example.com host 127.0.0.1:8080
```
**检查服务器支持:**
- 确认服务器支持 WebSocket
- 检查 WebSocket 端口是否开放
**检查防火墙:**
- 允许 WebSocket 端口
- 检查代理设置
#### 2. WebSocket 消息丢失
**问题:**
WebSocket 消息部分丢失
**解决方法:**
**检查网络稳定性:**
- 使用稳定的网络
- 避免频繁切换网络
**检查服务器负载:**
- 服务器可能过载
- 增加服务器资源
**检查心跳机制:**
- 实现心跳检测
- 自动重连机制
### 插件问题
#### 1. 插件安装失败
**问题:**
无法安装 whistle 插件
**解决方法:**
**检查 npm 源:**
```bash
npm config get registry
# 如果不是官方源,切换到官方源
npm config set registry https://registry.npmjs.org/
```
**检查网络连接:**
- 确保可以访问 npm 仓库
- 使用代理或镜像
**使用淘宝镜像:**
```bash
npm config set registry https://registry.npmmirror.com/
```
#### 2. 插件运行错误
**问题:**
插件安装后运行报错
**解决方法:**
**查看错误日志:**
```bash
w2 log
```
**检查插件版本:**
- 确认插件版本与 whistle 版本兼容
- 更新插件到最新版本
**检查插件依赖:**
- 安装插件依赖
```bash
npm install
```
### 数据问题
#### 1. 配置丢失
**问题:**
whistle 配置意外丢失
**解决方法:**
**恢复备份:**
```bash
cp ~/.whistle/rules.backup ~/.whistle/rules
```
**从 Git 恢复:**
```bash
git checkout ~/.whistle/rules
```
**重新配置:**
- 重新添加规则
- 重新安装插件
#### 2. 日志过大
**问题:**
whistle 日志文件过大
**解决方法:**
**清空日志:**
```bash
w2 log clear
```
**设置日志轮转:**
```bash
w2 log rotate
```
**定期清理:**
```bash
# 创建定时任务清理日志
crontab -e
# 添加:0 0 * * * w2 log clear
```
### 最佳实践
1. **定期备份配置**
- 使用 Git 管理配置
- 定期导出配置文件
- 保留历史版本
2. **保持更新**
- 定期更新 whistle
- 更新插件到最新版本
- 关注官方公告
3. **监控资源使用**
- 定期检查内存和 CPU
- 及时清理缓存
- 优化规则和脚本
4. **文档化配置**
- 添加规则注释
- 编写配置文档
- 记录问题解决方案
5. **使用脚本自动化**
- 自动化常用操作
- 减少手动操作
- 提高工作效率
前端 · 2月21日 16:27
whistle 和 Charles 有什么区别,如何选择使用?## 答案
Whistle 和 Charles 都是常用的网络调试代理工具,但它们在设计理念、功能特性和使用场景上有所不同。
### 核心差异对比
| 特性 | Whistle | Charles |
|------|---------|---------|
| 开源性质 | 完全开源免费 | 商业软件(有免费版) |
| 开发语言 | Node.js | Java |
| 配置方式 | 规则配置,更灵活 | 图形界面,更直观 |
| 插件系统 | 支持插件扩展 | 支持扩展 |
| 跨平台 | 完美支持 Windows/Mac/Linux | 主要支持 Windows/Mac |
| 学习曲线 | 需要学习规则语法 | 图形界面易上手 |
### Whistle 的优势
1. **规则配置更灵活**
- 支持复杂的规则组合
- 可以通过脚本实现自定义逻辑
- 规则可以版本控制
2. **开源免费**
- 无需付费即可使用全部功能
- 社区活跃,问题解决快
- 可以根据需求修改源码
3. **更适合团队协作**
- 规则配置可以共享
- 支持配置文件导入导出
- 适合集成到开发流程中
4. **性能更好**
- 基于 Node.js,启动速度快
- 内存占用相对较小
- 处理大量请求时更稳定
### Charles 的优势
1. **图形界面更友好**
- 可视化操作,无需记忆命令
- 适合不熟悉命令行的用户
- 界面美观,操作直观
2. **功能更全面**
- 内置更多调试工具
- 支持更多协议
- 提供更详细的请求分析
3. **适合快速调试**
- 启动即可使用
- 界面操作快速
- 适合临时调试任务
### 选择建议
**选择 Whistle 的场景:**
- 需要长期使用网络代理
- 团队协作开发
- 需要自定义复杂的代理逻辑
- 预算有限,需要免费工具
- 熟悉命令行和脚本
**选择 Charles 的场景:**
- 偶尔需要调试网络请求
- 更喜欢图形界面操作
- 需要快速上手使用
- 对可视化分析有更高要求
- 预算充足,愿意付费
### 总结
Whistle 更适合专业开发者和技术团队,特别是需要长期、深度使用网络代理的场景。Charles 更适合偶尔使用或偏好图形界面的用户。两者都是优秀的工具,选择哪个主要取决于个人习惯和具体需求。
前端 · 2月21日 16:27
如何开发 whistle 插件,插件的基本结构是什么?## 答案
Whistle 支持插件系统,可以通过开发插件来扩展其功能,实现自定义的网络请求处理逻辑。
### 插件开发基础
#### 1. 创建插件项目
```bash
mkdir whistle-plugin-demo
cd whistle-plugin-demo
npm init -y
```
#### 2. 创建插件入口文件
创建 `index.js` 文件:
```javascript
module.exports = function(server, options) {
// 插件初始化逻辑
console.log('Whistle plugin demo loaded');
// 监听请求事件
server.on('request', function(req, res) {
// 处理请求
if (req.url === '/api/plugin-demo') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
message: 'Hello from whistle plugin',
timestamp: Date.now()
}));
}
});
// 监听响应事件
server.on('response', function(req, res) {
// 处理响应
console.log('Response:', req.url, res.statusCode);
});
};
```
#### 3. 配置 package.json
```json
{
"name": "whistle-plugin-demo",
"version": "1.0.0",
"description": "A demo whistle plugin",
"main": "index.js",
"whistleConfig": {
"name": "demo",
"description": "Demo plugin for whistle"
}
}
```
### 插件功能实现
#### 1. 请求拦截和修改
```javascript
module.exports = function(server, options) {
server.on('request', function(req, res) {
// 修改请求头
req.headers['X-Custom-Header'] = 'Custom Value';
// 记录请求信息
console.log('Request URL:', req.url);
console.log('Request Method:', req.method);
console.log('Request Headers:', req.headers);
});
};
```
#### 2. 响应拦截和修改
```javascript
module.exports = function(server, options) {
server.on('response', function(req, res) {
// 修改响应头
res.setHeader('X-Response-Header', 'Custom Response');
// 修改响应体
const originalEnd = res.end;
res.end = function(chunk, encoding) {
if (chunk) {
const body = chunk.toString();
const modifiedBody = body.replace(/old/g, 'new');
originalEnd.call(res, modifiedBody, encoding);
} else {
originalEnd.call(res, chunk, encoding);
}
};
});
};
```
#### 3. 中间件模式
```javascript
module.exports = function(server, options) {
// 使用 Express 风格的中间件
server.use(function(req, res, next) {
console.log('Middleware:', req.url);
next();
});
// 路由处理
server.get('/api/test', function(req, res) {
res.json({ success: true });
});
};
```
### 插件配置选项
```javascript
module.exports = function(server, options) {
// 获取插件配置
const customConfig = options.customConfig || {};
const port = options.port || 3000;
console.log('Plugin options:', options);
};
```
### 安装和使用插件
#### 1. 本地安装插件
```bash
cd whistle-plugin-demo
npm link
w2 install demo
```
#### 2. 全局安装插件
```bash
npm install -g whistle-plugin-demo
w2 install demo
```
#### 3. 在规则中使用插件
```
www.example.com plugin://demo
```
### 高级功能
#### 1. WebSocket 支持
```javascript
module.exports = function(server, options) {
server.on('upgrade', function(req, socket, head) {
// 处理 WebSocket 升级请求
console.log('WebSocket upgrade:', req.url);
});
};
```
#### 2. 文件系统操作
```javascript
const fs = require('fs');
const path = require('path');
module.exports = function(server, options) {
server.on('request', function(req, res) {
if (req.url === '/api/file') {
const filePath = path.join(__dirname, 'data.json');
const data = fs.readFileSync(filePath, 'utf8');
res.end(data);
}
});
};
```
#### 3. 数据库集成
```javascript
const mysql = require('mysql');
module.exports = function(server, options) {
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test'
});
server.on('request', function(req, res) {
if (req.url === '/api/users') {
connection.query('SELECT * FROM users', function(error, results) {
if (error) {
res.statusCode = 500;
res.end(JSON.stringify({ error: error.message }));
} else {
res.end(JSON.stringify(results));
}
});
}
});
};
```
### 最佳实践
1. **错误处理**
- 添加适当的错误处理逻辑
- 记录错误日志
- 提供友好的错误信息
2. **性能优化**
- 避免阻塞操作
- 使用缓存减少重复计算
- 合理使用异步操作
3. **安全性**
- 验证输入参数
- 防止注入攻击
- 敏感信息加密存储
4. **文档和测试**
- 编写清晰的使用文档
- 添加单元测试
- 提供示例代码
前端 · 2月21日 16:26
whistle 支持哪些协议,如何处理不同协议的代理?## 答案
Whistle 支持多种协议的代理,包括 HTTP、HTTPS、WebSocket、HTTP/2 等,可以满足不同场景的调试需求。
### 支持的协议
#### 1. HTTP 协议
**基本代理:**
```
www.example.com host 127.0.0.1:8080
```
**转发代理:**
```
www.example.com forward http://127.0.0.1:8080
```
**修改请求:**
```
www.example.com reqHeaders://{custom-headers.json}
```
#### 2. HTTPS 协议
**基本代理:**
```
www.example.com host 127.0.0.1:8443
```
**启用 HTTPS 拦截:**
```
pattern whistle.https://
```
**配置 HTTPS 证书:**
1. 下载根证书
2. 安装到系统
3. 启用 HTTPS 拦截
#### 3. WebSocket 协议
**基本代理:**
```
ws://example.com host 127.0.0.1:8080
wss://example.com host 127.0.0.1:8080
```
**转发代理:**
```
ws://example.com forward ws://127.0.0.1:8080
wss://example.com forward wss://127.0.0.1:8080
```
**WebSocket 消息捕获:**
- 自动捕获连接建立
- 记录发送和接收的消息
- 显示连接状态
#### 4. HTTP/2 协议
Whistle 支持 HTTP/2 协议的代理:
- 自动降级到 HTTP/1.1
- 支持 HTTP/2 的多路复用
- 支持服务器推送
#### 5. SOCKS 代理
**配置 SOCKS 代理:**
```
www.example.com socks://127.0.0.1:1080
```
**SOCKS5 代理:**
```
www.example.com socks5://127.0.0.1:1080
```
### 协议转换
#### 1. HTTP 转 HTTPS
**配置规则:**
```
http://www.example.com forward https://www.example.com
```
#### 2. HTTPS 转 HTTP
**配置规则:**
```
https://www.example.com forward http://www.example.com
```
#### 3. WebSocket 转 HTTP
**配置规则:**
```
ws://example.com forward http://127.0.0.1:8080
```
### 协议特定配置
#### 1. HTTP 协议配置
**设置请求方法:**
```
www.example.com method://POST
```
**设置请求头:**
```
www.example.com reqHeaders://{http-headers.json}
```
**设置响应头:**
```
www.example.com resHeaders://{http-headers.json}
```
#### 2. HTTPS 协议配置
**禁用 SSL 验证:**
```
www.example.com disable://ssl
```
**设置 SSL 版本:**
```
www.example.com ssl://TLSv1.2
```
**自定义 CA 证书:**
```
www.example.com ca://{custom-ca.crt}
```
#### 3. WebSocket 协议配置
**设置 WebSocket 子协议:**
```
ws://example.com protocol://chat
```
**设置 WebSocket 超时:**
```
ws://example.com timeout://30000
```
**设置 WebSocket 心跳:**
```
ws://example.com ping://30000
```
### 多协议场景
#### 1. 混合协议代理
**同时代理 HTTP 和 HTTPS:**
```
www.example.com host 127.0.0.1:8080
api.example.com host 127.0.0.1:8080
```
**同时代理 WebSocket 和 HTTP:**
```
ws://example.com host 127.0.0.1:8080
www.example.com host 127.0.0.1:8080
```
#### 2. 协议路由
**根据协议路由:**
```
# HTTP 路由到本地
http://www.example.com host 127.0.0.1:8080
# HTTPS 路由到测试服务器
https://www.example.com host test.example.com
# WebSocket 路由到本地
ws://www.example.com host 127.0.0.1:8080
```
#### 3. 协议转换场景
**开发环境使用 HTTP,生产环境使用 HTTPS:**
```
# 开发环境
www.example.com forward http://127.0.0.1:3000
# 生产环境
www.example.com forward https://api.example.com
```
### 协议调试技巧
#### 1. 查看协议信息
在 whistle 管理界面中:
1. 点击 "Network" 标签
2. 点击请求查看详情
3. 查看 "General" 标签中的协议信息
#### 2. 协议降级测试
**测试 HTTP/2 降级:**
```
www.example.com disable://h2
```
**测试 WebSocket 降级:**
```
ws://example.com disable://websocket
```
#### 3. 协议性能测试
**测试不同协议的性能:**
```
# HTTP/1.1
www.example.com disable://h2
# HTTP/2
www.example.com enable://h2
```
### 协议安全
#### 1. HTTPS 安全
**启用 HTTPS 拦截:**
```
pattern whistle.https://
```
**验证证书:**
```
www.example.com verify://ssl
```
**禁用不安全的协议:**
```
www.example.com disable://ssl3
www.example.com disable://tls1
```
#### 2. WebSocket 安全
**使用 WSS:**
```
wss://example.com host 127.0.0.1:8080
```
**验证 WebSocket 握手:**
```
ws://example.com verify://websocket
```
### 协议兼容性
#### 1. 浏览器兼容性
- **Chrome/Edge**:完全支持所有协议
- **Firefox**:支持 HTTP、HTTPS、WebSocket
- **Safari**:支持 HTTP、HTTPS、WebSocket
#### 2. 服务器兼容性
- **Nginx**:支持 HTTP、HTTPS、WebSocket
- **Apache**:支持 HTTP、HTTPS
- **Node.js**:支持所有协议
#### 3. 移动端兼容性
- **iOS**:支持 HTTP、HTTPS、WebSocket
- **Android**:支持 HTTP、HTTPS、WebSocket
### 协议最佳实践
#### 1. 开发环境
- 使用 HTTP 协议便于调试
- 使用 WebSocket 实时通信
- 禁用 SSL 验证加快速度
#### 2. 测试环境
- 使用 HTTPS 模拟生产环境
- 使用 WSS 测试安全连接
- 启用 SSL 验证确保安全
#### 3. 生产环境
- 使用 HTTPS 确保安全
- 使用 WSS 保护 WebSocket
- 启用所有安全验证
### 协议故障排查
#### 1. HTTPS 连接失败
**检查项:**
- 证书是否正确安装
- SSL 版本是否匹配
- 防火墙是否阻止
**解决方法:**
```
www.example.com disable://ssl
```
#### 2. WebSocket 连接失败
**检查项:**
- 代理规则是否正确
- 服务器是否支持 WebSocket
- 网络是否稳定
**解决方法:**
```
ws://example.com forward ws://127.0.0.1:8080
```
#### 3. 协议不兼容
**检查项:**
- 客户端和服务器协议版本
- 浏览器支持情况
- 服务器配置
**解决方法:**
```
www.example.com disable://h2
```
前端 · 2月21日 16:26
whistle 如何与其他开发工具集成,有哪些集成方案?## 答案
Whistle 支持与其他开发工具集成,可以构建完整的开发和调试工作流。
### 与浏览器集成
#### 1. Chrome DevTools 集成
**使用 Chrome DevTools 调试:**
1. 配置浏览器代理指向 whistle
2. 打开 Chrome DevTools
3. 查看 Network 标签
4. whistle 捕获的请求会显示在 DevTools 中
**优势:**
- 结合 Chrome DevTools 的强大功能
- 查看详细的请求和响应信息
- 使用 Chrome 的性能分析工具
#### 2. Firefox Developer Tools 集成
**配置 Firefox 代理:**
1. 打开 Firefox 设置
2. 配置代理指向 whistle
3. 打开 Developer Tools
4. 查看 Network Monitor
**优势:**
- Firefox 的网络监控功能
- 查看 WebSocket 连接
- 分析网络性能
#### 3. Safari Web Inspector 集成
**配置 Safari 代理:**
1. 打开 Safari 偏好设置
2. 配置代理指向 whistle
3. 启用开发菜单
4. 打开 Web Inspector
**优势:**
- 适合 iOS 开发
- 查看 iOS 设备的网络请求
- 调试 Safari 特定问题
### 与编辑器集成
#### 1. VS Code 集成
**安装 whistle 插件:**
```bash
code --install-extension whistle-for-vscode
```
**使用 VS Code 编辑规则:**
1. 打开 whistle 配置文件
2. 使用 VS Code 编辑规则
3. 保存后自动生效
**优势:**
- 语法高亮
- 自动补全
- 错误提示
#### 2. WebStorm 集成
**配置 WebStorm:**
1. 打开 Settings
2. 配置 HTTP Proxy
3. 指向 whistle 代理地址
**优势:**
- 内置的 HTTP 客户端
- 直接测试 API
- 查看请求响应
#### 3. Vim/Neovim 集成
**使用 Vim 编辑规则:**
```vim
" 配置语法高亮
autocmd BufRead,BufNewFile *.rules set filetype=whistle
```
**优势:**
- 快速编辑
- 自定义配置
- 键盘操作
### 与构建工具集成
#### 1. Webpack 集成
**配置 Webpack 代理:**
```javascript
// webpack.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8899',
changeOrigin: true
}
}
}
};
```
**优势:**
- 开发服务器自动代理
- 热重载时保持代理
- 统一的开发环境
#### 2. Vite 集成
**配置 Vite 代理:**
```javascript
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8899',
changeOrigin: true
}
}
}
};
```
**优势:**
- 快速的开发服务器
- 原生 ES 模块支持
- 更好的热更新
#### 3. Create React App 集成
**配置代理:**
```json
// package.json
{
"proxy": "http://127.0.0.1:8899"
}
```
**优势:**
- 零配置代理
- 适合 React 项目
- 自动处理跨域
### 与测试工具集成
#### 1. Jest 集成
**配置 Jest 测试:**
```javascript
// jest.config.js
module.exports = {
setupFilesAfterEnv: ['<rootDir>/setup-whistle.js']
};
```
**setup-whistle.js:**
```javascript
// 配置 whistle 用于测试
const { setupWhistle } = require('jest-whistle');
setupWhistle({
rules: {
'api.example.com': 'host 127.0.0.1:3000'
}
});
```
**优势:**
- 测试时使用真实代理
- 模拟网络请求
- 集成测试环境
#### 2. Cypress 集成
**配置 Cypress:**
```javascript
// cypress.config.js
module.exports = {
e2e: {
setupNodeEvents(on, config) {
on('before:browser:launch', (browser, launchOptions) => {
// 配置浏览器代理
launchOptions.args.push(`--proxy-server=http://127.0.0.1:8899`);
});
}
}
};
```
**优势:**
- E2E 测试时使用代理
- 捕获测试请求
- 调试测试问题
#### 3. Playwright 集成
**配置 Playwright:**
```javascript
// playwright.config.js
module.exports = {
use: {
proxy: {
server: 'http://127.0.0.1:8899'
}
}
};
```
**优势:**
- 跨浏览器测试
- 自动化代理配置
- 网络请求拦截
### 与 CI/CD 集成
#### 1. GitHub Actions 集成
**配置 GitHub Actions:**
```yaml
name: CI
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install whistle
run: npm install -g whistle
- name: Start whistle
run: w2 start
- name: Run tests
run: npm test
- name: Stop whistle
run: w2 stop
```
**优势:**
- 自动化测试
- 持续集成
- 统一测试环境
#### 2. Jenkins 集成
**配置 Jenkins Pipeline:**
```groovy
pipeline {
agent any
stages {
stage('Setup') {
steps {
sh 'npm install -g whistle'
sh 'w2 start'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Cleanup') {
steps {
sh 'w2 stop'
}
}
}
}
```
**优势:**
- 灵活的流水线
- 自定义测试步骤
- 集成其他工具
#### 3. GitLab CI 集成
**配置 GitLab CI:**
```yaml
stages:
- test
test:
stage: test
script:
- npm install -g whistle
- w2 start
- npm test
- w2 stop
```
**优势:**
- 内置 CI/CD
- 简单配置
- 自动化部署
### 与监控工具集成
#### 1. Sentry 集成
**配置 Sentry:**
```javascript
const Sentry = require('@sentry/node');
Sentry.init({
dsn: 'your-dsn',
beforeSend(event) {
// 添加 whistle 请求信息
event.request = {
...event.request,
headers: {
'X-Whistle-Request': 'true'
}
};
return event;
}
});
```
**优势:**
- 错误追踪
- 请求上下文
- 性能监控
#### 2. New Relic 集成
**配置 New Relic:**
```javascript
const newrelic = require('newrelic');
// 添加 whistle 请求信息
newrelic.setTransactionName('whistle-request');
```
**优势:**
- 应用性能监控
- 请求追踪
- 错误分析
#### 3. Datadog 集成
**配置 Datadog:**
```javascript
const tracer = require('dd-trace').init();
// 追踪 whistle 请求
tracer.trace('whistle-request', () => {
// 请求处理逻辑
});
```
**优势:**
- 分布式追踪
- 性能分析
- 实时监控
### 与文档工具集成
#### 1. Swagger/OpenAPI 集成
**生成 whistle 规则:**
```javascript
const swaggerParser = require('swagger-parser');
const fs = require('fs');
swaggerParser.parse('swagger.json')
.then(api => {
const rules = [];
Object.keys(api.paths).forEach(path => {
const fullPath = api.host + path;
rules.push(`${fullPath} host 127.0.0.1:3000`);
});
fs.writeFileSync('whistle-rules.txt', rules.join('\n'));
});
```
**优势:**
- 自动生成规则
- API 文档同步
- 接口测试
#### 2. Postman 集成
**导出 Postman 集合:**
1. 在 Postman 中配置代理
2. 导出集合为 JSON
3. 转换为 whistle 规则
**优势:**
- API 测试
- 集合管理
- 团队协作
#### 3. GraphQL 集成
**配置 GraphQL 代理:**
```
graphql.example.com host 127.0.0.1:4000
graphql.example.com reqHeaders://{graphql-headers.json}
```
**优势:**
- GraphQL 调试
- 查询优化
- Schema 验证
### 最佳实践
1. **选择合适的集成方式**
- 根据项目需求选择
- 考虑团队技术栈
- 评估维护成本
2. **保持配置简洁**
- 避免过度集成
- 定期清理配置
- 文档化集成方案
3. **自动化集成流程**
- 使用脚本自动化
- 集成到 CI/CD
- 定期测试集成
4. **监控集成效果**
- 跟踪性能指标
- 收集使用反馈
- 持续优化集成
前端 · 2月21日 16:26
whistle 如何实现数据模拟,有哪些常用的模拟方法?## 答案
Whistle 提供了强大的数据模拟功能,可以在前端开发中模拟接口返回数据,提高开发效率。
### 数据模拟方法
#### 1. 使用 resBody 操作符
直接指定模拟数据:
```
www.example.com/api/user resBody://{"code":0,"data":{"name":"张三","age":25}}
```
#### 2. 使用 Values 文件
创建 Values 文件存储模拟数据:
**创建文件:`mock-user.json`**
```json
{
"code": 0,
"data": {
"id": 1,
"name": "张三",
"age": 25,
"email": "zhangsan@example.com"
}
}
```
**配置规则:**
```
www.example.com/api/user resBody://{mock-user.json}
```
#### 3. 使用 resScript 动态生成数据
创建脚本文件动态生成响应:
**创建文件:`mock-user.js`**
```javascript
module.exports = function(req, res) {
const userId = req.query.id || 1;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
code: 0,
data: {
id: userId,
name: `用户${userId}`,
timestamp: Date.now()
}
}));
};
```
**配置规则:**
```
www.example.com/api/user resScript://{mock-user.js}
```
#### 4. 使用 whistle 插件
开发 whistle 插件实现更复杂的模拟逻辑:
```javascript
module.exports = function(server, options) {
server.on('request', function(req, res) {
if (req.url === '/api/mock') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ mock: true }));
}
});
};
```
### 高级模拟技巧
#### 1. 延迟响应
```
www.example.com/api/* resScript://{delay-response.js}
```
**delay-response.js:**
```javascript
module.exports = function(req, res) {
setTimeout(() => {
res.end(JSON.stringify({ code: 0, data: 'success' }));
}, 2000); // 延迟2秒
};
```
#### 2. 错误模拟
```
www.example.com/api/error resBody://{"code":500,"message":"服务器错误"}
```
#### 3. 条件模拟
根据请求参数返回不同数据:
```javascript
module.exports = function(req, res) {
const type = req.query.type;
let data;
if (type === 'success') {
data = { code: 0, message: '成功' };
} else if (type === 'error') {
data = { code: 500, message: '失败' };
} else {
data = { code: 400, message: '参数错误' };
}
res.end(JSON.stringify(data));
};
```
### 最佳实践
1. **使用 Values 文件管理静态数据**
2. **使用 resScript 处理动态数据**
3. **按功能模块组织模拟数据**
4. **添加注释说明模拟数据的用途**
5. **定期清理不再使用的模拟规则**
前端 · 2月21日 16:26
whistle 的 Values 功能是什么,如何使用和管理 Values?## 答案
Whistle 提供了强大的 Values 功能,可以存储和管理各种配置数据,在规则中灵活使用。
### Values 基础
#### 1. 什么是 Values
Values 是 whistle 提供的一种数据存储机制,可以存储:
- 配置数据
- 模拟数据
- 常量值
- 环境变量
#### 2. Values 文件格式
Values 文件支持多种格式:
- **JSON 格式**:`values.json`
- **Properties 格式**:`values.properties`
- **INI 格式**:`values.ini`
- **YAML 格式**:`values.yaml`
### 创建和使用 Values
#### 1. 创建 JSON 格式的 Values
**创建文件:`values.json`**
```json
{
"local-host": "127.0.0.1",
"local-port": "3000",
"test-host": "test.example.com",
"test-port": "8080",
"api-base": "https://api.example.com",
"timeout": "5000",
"retry-count": "3"
}
```
**在规则中使用:**
```
www.example.com host {{local-host}}:{{local-port}}
api.example.com forward {{api-base}}
```
#### 2. 创建 Properties 格式的 Values
**创建文件:`values.properties`**
```
local.host=127.0.0.1
local.port=3000
test.host=test.example.com
test.port=8080
api.base=https://api.example.com
timeout=5000
retry.count=3
```
**在规则中使用:**
```
www.example.com host {{local.host}}:{{local.port}}
api.example.com forward {{api.base}}
```
#### 3. 创建 INI 格式的 Values
**创建文件:`values.ini`**
```ini
[local]
host=127.0.0.1
port=3000
[test]
host=test.example.com
port=8080
[api]
base=https://api.example.com
timeout=5000
retry=3
```
**在规则中使用:**
```
www.example.com host {{local.host}}:{{local.port}}
api.example.com forward {{api.base}}
```
### Values 高级用法
#### 1. 嵌套对象
**创建嵌套的 Values:**
```json
{
"servers": {
"local": {
"host": "127.0.0.1",
"port": "3000"
},
"test": {
"host": "test.example.com",
"port": "8080"
}
},
"api": {
"base": "https://api.example.com",
"version": "v1"
}
}
```
**在规则中使用:**
```
www.example.com host {{servers.local.host}}:{{servers.local.port}}
api.example.com forward {{api.base}}/{{api.version}}
```
#### 2. 数组数据
**创建包含数组的 Values:**
```json
{
"allowed-origins": [
"https://www.example.com",
"https://test.example.com",
"https://localhost:3000"
],
"api-endpoints": [
"/api/user",
"/api/list",
"/api/detail"
]
}
```
**在规则中使用:**
```
# 使用数组的第一个元素
www.example.com resHeaders://{cors-{{allowed-origins.0}}.json}
```
#### 3. 环境变量
**创建环境变量 Values:**
```json
{
"env": "development",
"api-url": "https://dev-api.example.com",
"debug": true
}
```
**在规则中使用:**
```
# 根据环境变量配置
www.example.com forward {{api-url}}
www.example.com reqHeaders://{debug-{{debug}}.json}
```
### Values 在脚本中的使用
#### 1. 在 reqScript 中使用
**创建脚本:`use-values.js`**
```javascript
const values = require('./values.json');
module.exports = function(req, res) {
// 使用 Values 中的数据
const timeout = values.timeout || 5000;
const retryCount = values['retry-count'] || 3;
req.headers['X-Timeout'] = timeout;
req.headers['X-Retry-Count'] = retryCount;
};
```
**配置规则:**
```
www.example.com reqScript://{use-values.js}
```
#### 2. 在 resScript 中使用
**创建脚本:`use-values-res.js`**
```javascript
const values = require('./values.json');
module.exports = function(req, res) {
const originalEnd = res.end;
res.end = function(chunk, encoding) {
if (chunk) {
const body = chunk.toString();
const jsonData = JSON.parse(body);
// 使用 Values 中的数据
jsonData.apiVersion = values.api.version;
jsonData.environment = values.env;
originalEnd.call(res, JSON.stringify(jsonData), encoding);
} else {
originalEnd.call(res, chunk, encoding);
}
};
};
```
**配置规则:**
```
www.example.com resScript://{use-values-res.js}
```
#### 3. 在插件中使用
**创建插件:`values-plugin.js`**
```javascript
const fs = require('fs');
const path = require('path');
module.exports = function(server, options) {
// 读取 Values 文件
const valuesPath = path.join(__dirname, 'values.json');
const values = JSON.parse(fs.readFileSync(valuesPath, 'utf8'));
server.on('request', function(req, res) {
// 使用 Values 中的数据
req.values = values;
// 根据环境变量处理请求
if (values.env === 'development') {
req.headers['X-Debug'] = 'true';
}
});
};
```
### Values 管理技巧
#### 1. 多环境 Values
**创建不同环境的 Values 文件:**
**values-dev.json:**
```json
{
"env": "development",
"api-url": "https://dev-api.example.com",
"debug": true
}
```
**values-test.json:**
```json
{
"env": "testing",
"api-url": "https://test-api.example.com",
"debug": true
}
```
**values-prod.json:**
```json
{
"env": "production",
"api-url": "https://api.example.com",
"debug": false
}
```
**切换环境:**
```bash
# 使用开发环境
cp values-dev.json values.json
# 使用测试环境
cp values-test.json values.json
# 使用生产环境
cp values-prod.json values.json
```
#### 2. Values 文件组织
**按功能模块组织:**
**api-values.json:**
```json
{
"api-base": "https://api.example.com",
"api-version": "v1",
"timeout": "5000"
}
```
**cors-values.json:**
```json
{
"allowed-origins": [
"https://www.example.com",
"https://test.example.com"
],
"allowed-methods": [
"GET",
"POST",
"PUT",
"DELETE"
]
}
```
**在规则中使用:**
```
api.example.com forward {{api-values.api-base}}/{{api-values.api-version}}
www.example.com resHeaders://{cors-values.json}
```
#### 3. Values 版本控制
**使用 Git 管理 Values 文件:**
```bash
# 初始化 Git 仓库
git init
# 添加 Values 文件
git add values.json
# 提交
git commit -m "Add values configuration"
# 推送到远程仓库
git push origin main
```
### Values 最佳实践
#### 1. 命名规范
- 使用小写字母和连字符:`local-host`
- 使用有意义的名称:`api-base-url`
- 避免使用特殊字符
#### 2. 数据类型
- 字符串:用引号包裹
- 数字:直接使用
- 布尔值:使用 `true` 或 `false`
- 数组:使用方括号
- 对象:使用花括号
#### 3. 注释说明
**在 Values 文件中添加注释:**
```json
{
"local-host": "127.0.0.1",
"local-port": "3000",
"api-base": "https://api.example.com",
"timeout": "5000"
}
```
**创建配套的 README 文件:**
```markdown
# Values 配置说明
## 配置项说明
- `local-host`: 本地服务器地址
- `local-port`: 本地服务器端口
- `api-base`: API 基础地址
- `timeout`: 请求超时时间(毫秒)
## 使用方法
在 whistle 规则中使用 `{{key}}` 引用配置项。
```
#### 4. 安全考虑
- 不要在 Values 中存储敏感信息
- 使用环境变量管理敏感数据
- 定期更新 Values 文件
### Values 实战示例
#### 1. 动态配置代理
**创建 Values:**
```json
{
"proxy": {
"enabled": true,
"host": "127.0.0.1",
"port": "8080"
}
}
```
**配置规则:**
```
{{#if proxy.enabled}}
www.example.com host {{proxy.host}}:{{proxy.port}}
{{/if}}
```
#### 2. 多域名配置
**创建 Values:**
```json
{
"domains": {
"www": "www.example.com",
"api": "api.example.com",
"static": "static.example.com"
},
"servers": {
"local": "127.0.0.1:3000",
"test": "test.example.com:8080"
}
}
```
**配置规则:**
```
{{domains.www}} host {{servers.local}}
{{domains.api}} forward https://{{servers.test}}
{{domains.static}} host {{servers.local}}
```
#### 3. 条件配置
**创建 Values:**
```json
{
"features": {
"new-feature": true,
"beta-feature": false
}
}
```
**配置规则:**
```
{{#if features.new-feature}}
www.example.com/new-feature resBody://{new-feature.json}
{{/if}}
{{#if features.beta-feature}}
www.example.com/beta resBody://{beta-feature.json}
{{/if}}
```
前端 · 2月21日 16:26
whistle 如何管理配置规则,如何进行团队协作?## 答案
Whistle 提供了多种方式来管理配置规则,包括通过 Web 界面、命令行和配置文件进行管理,支持团队协作和版本控制。
### 配置规则管理方式
#### 1. Web 界面管理
**访问管理界面:**
```
http://127.0.0.1:8899/
```
**操作步骤:**
1. 点击 "Rules" 标签
2. 在编辑器中添加或修改规则
3. 点击 "Save" 保存规则
4. 规则立即生效
**优点:**
- 可视化操作,直观易用
- 实时预览规则效果
- 适合快速调试
#### 2. 命令行管理
**启动 whistle:**
```bash
# 启动 whistle
w2 start
# 指定端口启动
w2 start -p 8080
# 指定配置文件启动
w2 start -f custom.rules
```
**停止 whistle:**
```bash
w2 stop
```
**重启 whistle:**
```bash
w2 restart
```
**查看运行状态:**
```bash
w2 status
```
#### 3. 配置文件管理
**默认配置文件位置:**
- **Windows**: `C:\Users\{username}\.whistle\rules`
- **Mac/Linux**: `~/.whistle/rules`
**配置文件格式:**
```
# 注释:这是规则说明
# 基本规则
www.example.com host 127.0.0.1:8080
# 分组规则
# 本地开发
www.local.com host 127.0.0.1:3000
api.local.com host 127.0.0.1:3001
# 测试环境
www.test.com host test.example.com
api.test.com host api-test.example.com
# 生产环境
www.prod.com host prod.example.com
```
### 规则优先级
#### 1. 匹配顺序
Whistle 按照规则在配置文件中的顺序从上到下匹配,一旦匹配成功就不再继续匹配后续规则。
#### 2. 优先级规则
- **精确匹配 > 通配符匹配 > 正则表达式匹配**
- **更具体的规则应该放在前面**
- **使用 `#` 注释来组织规则**
#### 3. 规则示例
```
# 精确匹配(优先级最高)
www.example.com/api/user host 127.0.0.1:8080
# 通配符匹配
*.example.com/api/* host 127.0.0.1:8080
# 正则表达式匹配(优先级最低)
/^https:\/\/www\.example\.com\/api\/.*/ host 127.0.0.1:8080
```
### 团队协作管理
#### 1. 配置文件版本控制
**使用 Git 管理配置文件:**
```bash
# 初始化 Git 仓库
cd ~/.whistle
git init
# 添加配置文件
git add rules
# 提交配置
git commit -m "Add whistle rules"
# 推送到远程仓库
git remote add origin https://github.com/your-org/whistle-rules.git
git push -u origin main
```
#### 2. 共享配置文件
**方法一:通过 Git 共享**
- 将配置文件放在 Git 仓库中
- 团队成员克隆仓库
- 使用符号链接到 whistle 配置目录
```bash
# 克隆配置仓库
git clone https://github.com/your-org/whistle-rules.git ~/whistle-config
# 创建符号链接
ln -s ~/whistle-config/rules ~/.whistle/rules
```
**方法二:通过配置文件导入导出**
- 导出配置文件
- 通过团队协作工具分享
- 其他成员导入配置
#### 3. 环境配置分离
**创建不同环境的配置文件:**
```
# 开发环境
rules-dev:
www.dev.com host 127.0.0.1:3000
api.dev.com host 127.0.0.1:3001
# 测试环境
rules-test:
www.test.com host test.example.com
api.test.com host api-test.example.com
# 生产环境
rules-prod:
www.prod.com host prod.example.com
api.prod.com host api-prod.example.com
```
**切换环境:**
```bash
# 使用开发环境配置
w2 start -f rules-dev
# 使用测试环境配置
w2 start -f rules-test
# 使用生产环境配置
w2 start -f rules-prod
```
### 配置管理最佳实践
#### 1. 规则组织
**按功能分组:**
```
# 本地开发服务
# ====================
www.local.com host 127.0.0.1:3000
api.local.com host 127.0.0.1:3001
# 测试环境
# ====================
www.test.com host test.example.com
api.test.com host api-test.example.com
# 数据模拟
# ====================
www.example.com/api/user resBody://{mock-user.json}
www.example.com/api/list resBody://{mock-list.json}
```
#### 2. 注释规范
**添加清晰的注释:**
```
# 用户接口模拟
# 用于前端开发,模拟用户数据
www.example.com/api/user resBody://{mock-user.json}
# 跨域处理
# 解决开发环境跨域问题
www.example.com resHeaders://{cors-headers.json}
```
#### 3. 配置备份
**定期备份配置:**
```bash
# 备份当前配置
cp ~/.whistle/rules ~/.whistle/rules.backup.$(date +%Y%m%d)
# 恢复配置
cp ~/.whistle/rules.backup.20240101 ~/.whistle/rules
```
#### 4. 配置验证
**验证规则语法:**
- 在 Web 界面中检查规则是否高亮
- 查看规则是否生效
- 测试规则是否按预期工作
### 高级配置管理
#### 1. 使用 Values 文件
**创建 Values 文件存储配置:**
**创建文件:`values.json`**
```json
{
"local-host": "127.0.0.1",
"local-port": "3000",
"test-host": "test.example.com",
"mock-data": {
"user": {
"name": "张三",
"age": 25
}
}
}
```
**在规则中使用:**
```
www.example.com host {{local-host}}:{{local-port}}
```
#### 2. 使用插件扩展配置
**开发配置管理插件:**
```javascript
module.exports = function(server, options) {
server.on('request', function(req, res) {
// 根据环境变量动态配置
const env = process.env.NODE_ENV || 'development';
if (env === 'development') {
req.headers['X-Environment'] = 'dev';
} else if (env === 'production') {
req.headers['X-Environment'] = 'prod';
}
});
};
```
#### 3. 自动化配置
**使用脚本自动配置:**
```bash
#!/bin/bash
# auto-config.sh
# 获取当前环境
ENV=${1:-dev}
# 复制对应环境的配置文件
cp ~/.whistle/rules-$ENV ~/.whistle/rules
# 重启 whistle
w2 restart
echo "Whistle configured for $ENV environment"
```
**使用脚本:**
```bash
./auto-config.sh dev # 配置开发环境
./auto-config.sh test # 配置测试环境
./auto-config.sh prod # 配置生产环境
```
### 常见问题解决
#### 1. 规则不生效
**检查项:**
- 确认规则语法正确
- 检查规则优先级
- 确认 whistle 正在运行
- 清除浏览器缓存
#### 2. 配置冲突
**解决方法:**
- 使用更具体的规则
- 调整规则顺序
- 使用注释标记规则用途
#### 3. 配置文件损坏
**恢复方法:**
- 从备份恢复
- 重新初始化配置
- 使用版本控制恢复
前端 · 2月21日 16:26