operation
在 Whistle 中,每条规则由 匹配模式(pattern) 和 操作(operation) 两部分组成,其中 operation 的通用语法为:
protocol://[value]- protocol:指定操作类型(如
file、proxy、resReplace等) - value:操作内容(支持多种格式,见下文)
内联值
pattern reqHeaders://x-proxy=Whistle # 设置请求头
pattern statusCode://404 # 修改状态码
pattern file://({"ec":0}) # 用内联内容(小括号里面的值:`{"ec":0}`)响应请求当操作内容(Value)包含空格、换行符或特殊字符时,无法直接使用内联方式(Inline),需改用以下方法:
内嵌值
``` ua.txt
Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1
```
pattern ua://{ua.txt}等价于
``` headers.json
user-agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1
```
pattern reqHeaders://{headers.json}Values 引用
当操作值(Value)需要被多个规则共享时,直接内嵌在规则中会导致无法复用。此时可以将这些值存储在 Whistle 界面的 Values 模块中,并通过键名引用:
- 在 Values 里面创建一个名为
result.json的 key 后,填入操作内容 - 在规则里面即可通过
{result.json}的方式引用,如:www.test.com/cgi-bin/test file://{result.json}

文件/远程资源
pattern reqHeaders:///User/xxx/filepath # 从本地文件加载操作内容
pattern resHeadrs://https://example.com/config.json # 从远处加载 JSON 对象
pattern resHeaders://temp/blank.json # 通过边境临时文件⚠️ 注意:http/https/ws/wss/tunnel/host/enable/cache... 等协议禁止通过文件路径或远程 URL 获取内容,详见各协议文档。
临时文件
当需要频繁编辑内容时,可以使用 Whistle 提供的临时文件功能。
pattern protocol://temp.json操作步骤:
- 在 Rules 编辑器中,按住
Command(Mac)/Ctrl(Windows) - 鼠标点击
protocol://temp.json - 在弹出的编辑对话框中输入响应内容
- 点击
Save保存
小括号用途
在 Whistle 规则中,protocol://value 的 value 部分可能有三种间接引用类型:
{key}- 引用内嵌值remote-url- 远程资源地址localfilepath- 本地文件路径
当需要直接引用上述内容本身(而非它们间接引用内容)作为操作内容时,可以用小括号包裹:
protocol://(value)示例:
reqHeaders:///User/xxx/yyy.txt- 从本地文件/User/xxx/yyy.txt加载操作内容reqHeaders://(/User/xxx/yyy.txt)- 将/User/xxx/yyy.txt直接作为操作内容
模板字符串
Whistle 提供了类似 ES6 的模板字符串功能,允许您动态引用请求信息并应用到规则配置中。支持以下几种模板字符串:
一般内敛值
pattern protocol://`...${version}...`内嵌值或 Values 引用
``` test.key
...${reqId}...
...${version}...
```
pattern protocol://`{test.key}`小括号内容
pattern protocol://`(...${now}...)`字符串变量
| 变量名称 | 取值 |
|---|---|
${now} | Date.now() |
${random} | Math.random() |
${randomUUID} | crypto.randomUUID() |
${randomInt(n)} 或 ${randomInt(n1-n2)} | 从 [0, n] 或 [n1, n2] 取一个随机正整数 (Added in: v2.9.104) |
${reqId} | Whistle 给每个请求分配的 ID |
${url.protocol} | url.parse(fullUrl).protocol |
${url.hostname} | url.parse(fullUrl).hostname |
${url.host} | url.parse(fullUrl).host |
${url.port} | url.parse(fullUrl).port |
${url.path} | url.parse(fullUrl).path |
${url.pathname} | url.parse(fullUrl).pathname |
${url.search} | url.parse(fullUrl).search |
${query.xxx} | 请求参数 xxx 的值 |
${url} | 请求完整 URL |
${querystring} | url.parse(fullUrl).search || '?'(不为空) |
${searchstring} | url.parse(fullUrl).search || '?'(不为空) |
${method} | 请求方法 |
${reqHeaders.xxx} | 请求头字段 xxx 的值 |
${resHeaders.xxx} | 响应头字段 xxx 的值 |
${version} | Whistle 版本号 |
${port} | Whitle 端口号 |
${host} | Whistle 启动时监听的网卡 IP(默认为空) |
${realPort} | Whistle 界面 Online 对话框显示的 port(一般为 Whistle 端口号) |
${realHost} | Whistle 界面 Online 对话框显示的 host(一般为 Whistle 监听的网卡 IP) |
${clientIp} | 客户端 IP |
${clientPort} | 客户端端口 |
${serverIp} | 服务端 IP |
${serverPort} | 服务端端口 |
${reqCookies.xxx} | 请求 cookie xxx 的值 |
${resCookies.xxx} | 响应 cookie xxx 的值 |
${statusCode} | 响应状态码 |
${env.xxx} | process.env.xxx |
${whistle.plugin-name} | whistle.plugin-name://value 或 plugin-name://value 的 value |
${whistle.plugin-name}只在插件的内部规则才可能有值
示例
``` test.txt
now: ${now}
random: ${random}
randomUUID: ${randomUUID}
reqId: ${reqId}
url.protocol: ${url.protocol}
url.hostname: ${url.hostname}
url.host: ${url.host}
url.port: ${url.port}
url.path: ${url.path}
url.pathname: ${url.pathname}
url.search; ${url.search}
query: ${query.name}
url: ${url}
querystring: ${querystring}
searchstring: ${searchstring}
method: ${method}
reqHeaders.accept: ${reqHeaders.accept}
resHeaders.content-type: ${resHeaders.content-type}
version: ${version}
port: ${port}
host: ${host}
realPort: ${realPort}
realHost: ${realHost}
clientIp: ${clientIp}
clientPort: ${clientPort}
serverIp: ${serverIp}
serverPort: ${serverPort}
reqCookies.test: ${reqCookies.test}
resCookies.test: ${resCookies.test}
statusCode: ${statusCode}
env.USER: ${env.USER}
```
www.test.com/index.html file://`{test.txt}`访问 https://www.test.com/index.html?name=avenwu 则返回响应内容:
now: 1752301623295
random: 0.6819241513880432
randomUUID: e917b9fc-e2ef-4255-9209-11eb417235c5
reqId: 1752301623294-339
url.protocol: https:
url.hostname: www.test.com
url.host: www.test.com
url.port:
url.path: /index.html?name=avenwu
url.pathname: /index.html
url.search; ?name=avenwu
query: avenwu
url: https://www.test.com/index.html?name=avenwu
querystring: ?name=avenwu
searchstring: ?name=avenwu
method: GET
reqHeaders.accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
resHeaders.content-type:
version: 2.9.100
port: 8899
host:
realPort: 8899
realHost:
clientIp: 127.0.0.1
clientPort: 60582
serverIp:
serverPort:
reqCookies.test:
resCookies.test:
statusCode:
env.USER: av数据对象
操作内容除了文本或二进制内容,还有可能是 JSON 对象,Whistle 支持以下 3 种数据对象格式:
JSON 格式
{
"key1": value1,
"key2": value2,
"keyN": valueN
}行格式
key1: value1
key2:value2
keyN: valueN以
冒号+空格分隔,如果没有冒号+空格,则以第一个冒号分隔,如果没有冒号,则value为空字符串
多级嵌套:
a.b.c: 123
c\.d\.e: abc等价于:
{
"a": {
"b": {
"c": 123
}
},
"c.d.e": "abc"
}内联格式(请求参数格式)
key1=value1&key2=value2&keyN=valueN
key和value最好都encodeURIComponent
常见操作指令速查手册
一、修改请求内容
1.1 修改请求方法
# 基础语法
pattern method://新方法
# 示例
www.example.com/path method://post数据来源支持:
- 直接指定:
method://get - 内嵌值:
method://{keyOfEmbedded} - Values配置:
method://{keyOfValues}
注意事项:
- 方法名不区分大小写
- 不支持从本地文件或远程URL获取
实用示例:
# 示例1:将所有请求方法改为POST
www.example.com/path method://post
# 示例2:仅将PUT请求改为POST
www.example.com/path method://post includeFilter://m:put
# 示例3:根据请求体内容修改方法
www.example.com/api method://put includeFilter://b:cmdname=test1.2 修改请求 URL
URL映射
www.example.com/path/to www.test.com/test映射效果:
https://www.example.com/path/to?query=abc→https://www.test.com/test?query=abchttps://www.example.com/path/to/subpage→https://www.test.com/test/subpagewss://www.example.com/path/to/api→wss://www.test.com/test/api
修改请求参数
# 新增/替换参数
pattern urlParams://({"key":"value"})
# 删除参数
pattern delete://urlParams.paramName
# 示例:修改参数并删除指定参数
www.example.com/api urlParams://({"cmdname":"Test"}) delete://urlParams.oldParam修改Path路径
# 正则替换
pattern pathReplace://({"/old/ig":"new"})
# 关键字替换
pattern pathReplace://({"old":"new"})数据来源支持:
- 内联JSON
- 内嵌值
- Values配置
- 本地文件
- 远程URL
1.3 修改 HTTP 版本
# 强制使用普通HTTPS(禁用HTTP/2)
pattern disable://h2默认会尝试使用HTTP/2建立连接,不支持时自动降级为HTTPS
1.4 修改请求头
# 新增/替换请求头
pattern reqHeaders://({"Header-Name":"value"})
# 删除请求头
pattern delete://reqHeaders.headerName
# 示例
www.example.com reqHeaders://({"X-Custom-Header":"test"})1.5 修改请求体
合并修改(JSON/表单)
pattern reqMerge://({"newField":"value"})文本替换
# 正则替换
pattern reqReplace://({"/search/ig":"replace"})
# 关键字替换
pattern reqReplace://({"search":"replace"})完全替换
pattern reqBody://(新内容)删除操作
# 删除特定字段
pattern delete://reqBody.fieldName
# 删除整个请求体
pattern delete://reqBody数据来源支持:
- 内联值
- 内嵌值
- Values配置
- 本地文件
- 远程URL
二、修改响应内容
2.1 修改状态码
# 替换现有响应状态码(请求会到达服务器)
pattern replaceStatus://500
# 直接响应状态码(请求不发送到服务器)
pattern statusCode://5002.2 修改响应头
# 新增/替换响应头
pattern resHeaders://({"Header-Name":"value"})
# 删除响应头
pattern delete://resHeaders.headerName2.3 修改响应体
合并修改(JSON/JSONP)
pattern resMerge://({"newData":"value"})文本替换
pattern resReplace://({"/old/ig":"new"})替换响应体
# 替换服务器返回的内容
pattern resBody://(新内容)直接响应内容
# 请求不发送到服务器
pattern file://(直接返回的内容) resType://html删除操作
# 删除响应体字段
pattern delete://resBody.fieldName
# 清空响应体
pattern delete://resBody2.4 修改尾部响应头
Trailers是在分块传输响应后发送的额外头部字段
# 新增/替换Trailers
pattern trailers://({"Trailer-Name":"value"})
# 删除Trailers
pattern delete://trailers.trailerName三、修改连接过程
3.1 修改 DNS
# 设置IP地址
pattern 127.0.0.1
# 设置IP和端口
pattern 127.0.0.1:8080
# CNAME效果(指向其他主机)
pattern host://www.target.com:80803.2 设置代理
# HTTP代理
pattern proxy://127.0.0.1:8080
# SOCKS5代理
pattern socks://127.0.0.1:1080
# 支持域名
pattern proxy://proxy.example.com:80803.3 代理和 DNS 同时生效
优先级说明:
- 默认:host配置优先于proxy
- 可调整:通过
lineProps://proxyHost让两者同时生效
# 示例1:只生效host配置
pattern 127.0.0.1:8080 socks://10.1.1.1:1080
# 示例2:只生效proxy配置
pattern 127.0.0.1:8080 socks://10.1.1.1:1080 ignore://host
# 示例3:host和proxy同时生效
pattern 127.0.0.1:8080 socks://10.1.1.1:1080 lineProps://proxyHost四、页面调试工具
4.1 查看页面 DOM 结构
pattern weinre://调试会话名称详细用法参考:weinre文档
4.2 查看页面日志及错误信息
pattern log://日志会话名称详细用法参考:log文档
数据来源速查表
| 操作类型 | 直接内联 | 内嵌值 | Values | 本地文件 | 远程URL |
|---|---|---|---|---|---|
| 请求方法 | ✓ | ✓ | ✓ | ✗ | ✗ |
| URL参数 | ✓ | ✓ | ✓ | ✓ | ✓ |
| 请求头 | ✓ | ✓ | ✓ | ✓ | ✓ |
| 请求体 | ✓ | ✓ | ✓ | ✓ | ✓ |
| 响应头 | ✓ | ✓ | ✓ | ✓ | ✓ |
| 响应体 | ✓ | ✓ | ✓ | ✓ | ✓ |
| Trailers | ✓ | ✓ | ✓ | ✓ | ✓ |
语法示例:
# 直接内联
protocol://({"key":"value"})
# 内嵌值
protocol://{embeddedKey}
# Values配置
protocol://{valuesKey}
# 本地文件
protocol:///path/to/file.json
# 远程URL
protocol://https://example.com/data.json常用过滤条件
| 过滤器 | 说明 | 示例 |
|---|---|---|
includeFilter://m:方法 | 按请求方法过滤 | includeFilter://m:put |
includeFilter://b:内容 | 按请求体内容过滤 | includeFilter://b:cmdname=test |
| 正则表达式 | 区分大小写匹配 | /Test/ |
提示: 更多协议和高级用法请参考完整协议列表