Web接口环境切换插件-whistle.env-switcher
发布时间: 2026-03-26
whistle.env-switcher 项目简介
这是一个基于whistle(一款专门针对程序员使用的代理软件)的插件,可以做到在你开发的页面中注入一个环境切换按钮,直接页面中一键切换到本地、开发环境、测试环境、正式环境、某个同事的电脑启动的服务。
可以快速切换接口请求某个指定服务器,便于调试
在你的web中显示的效果,会在你的web中注入一个胶囊,点击后查看可选项。

可选项配置都在whistle插件配置页

什么是whistle
Whistle 是一款基于 Node.js 开发的、免费开源的跨平台 Web 调试代理工具,专门用来抓包、改包、代理、Mock 数据,前端 / 测试 / 后端都常用。
简单来说就是你可以把浏览器数据转发到whistle,然后再whistle中对所有请求做拦截处理、便于调试。
安装
1.安装whistle
whistle有两个版本,一个windows/mac图形程序,一个是命令行的,我试了一下两个的底层可能有些不一样,我用图形端没能成功安装上插件,推荐安装命令行版本,命令行不是
说没有图形界面,而是服务启动需要命令启动,启动后在浏览器中访问 127.0.0.1:8899 (默认端口)或者 http://local.whistlejs.com/ 即可看到一个和图形界面端一样的界面,
功能都是一样的。
安装命令端
npm i -g whistle启动服务命令
w2 start -p 8899 # 不用-p默认就是8899端口,用-p可以指定端口号
# 如果要停止服务
w2 stop安装后在浏览器输入 127.0.0.1:8899 (默认端口)或者 http://local.whistlejs.com/

2.安装ZeroOmega浏览器代理
为什么还需要安装浏览器代理? 因为你需要把浏览器的所有请求转发到whistle的8899端口上,否则浏览器就直接走dns解析的ip地址去了。
流量转发到你启动的whistle端口,我启动的是8083所以访问8083,你是多少就转发到多少

打开代理

这样所有的请求都会走到whistle的网络请求中可以看到了
3.安装whistle.env-switcher插件
安装插件直接执行
# 国内cnb
npm i -g whistle.env-switcher --registry=https://npm.cnb.cool/sojs/whistleplugin/-/packages/
# 或者走npmjs
npm i -g whistle.env-switcher全局安装插件后,重启一次whistle
w2 stop
w2 start -p 8899可以在插件列表看到插件了

点击option进入配置页面,配置是json格式

使用配置
要代理的话需要配置,配置就是指什么url转发到什么地方去,
根结构如下:
{
"version": 1,
"signalKeys": {
"projectQueryKey": "__wes_p",
"apiEnvQueryKey": "__wes_e",
"projectHeaderKey": "x-whistle-env-project",
"apiEnvHeaderKey": "x-whistle-env"
},
"projects": []
}最小可用示例
{
"version": 1,
"signalKeys": {
"projectQueryKey": "__wes_p",
"apiEnvQueryKey": "__wes_e",
"projectHeaderKey": "x-whistle-env-project",
"apiEnvHeaderKey": "x-whistle-env"
},
"projects": [
{
"key": "local",
"name": "本地项目",
"enabled": true,
"matchHosts": ["local.dev:8000"],
"matchPathPrefixes": ["/"],
"configPath": "/__env_config__",
"ui": {
"reloadOnApiSwitch": true
},
"frontendTargets": [
{
"key": "local-front",
"label": "本地前端",
"color": "#2563eb",
"target": "http://127.0.0.1:8000"
},
{
"key": "test-front",
"label": "测试前端",
"color": "#7c3aed",
"target": "https://test.example.com"
}
],
"defaultFrontendTargetKey": "local-front",
"routeGroups": [
{
"key": "api1",
"name": "api1",
"prefixes": ["/api"],
"defaultEnvKey": "default",
"envs": [
{
"key": "default",
"label": "本地环境",
"color": "#64748b",
"target": ""
},
{
"key": "test",
"label": "测试环境",
"color": "#f59e0b",
"target": "http://xxxx:8090/api"
}
]
},
{
"key": "api2",
"name": "api2",
"prefixes": ["/api2"],
"defaultEnvKey": "default",
"envs": [
{
"key": "default",
"label": "本地环境",
"color": "#64748b",
"target": ""
},
{
"key": "test",
"label": "测试环境",
"color": "#f59e0b",
"target": "http://xxxx:8090/api2"
}
]
}
]
}
]
}配置项说明
根级字段
version
- 配置版本号
- 当前固定为
1
signalKeys
- 定义运行时内部使用的 header / query key 名称
- 一般保持默认即可
字段说明:
projectQueryKey- 项目标记对应的 query key
- 现在主要用于兼容旧链路或手工排查
apiEnvQueryKey- API 环境标记对应的 query key
- 现在主要用于兼容旧链路或手工排查
projectHeaderKeyfetch/XHR请求中携带项目标识的 header 名
apiEnvHeaderKeyfetch/XHR请求中携带 API 环境标识的 header 名
projects
- 项目列表
- 一个配置里可以放多个项目
单个项目字段
key
- 项目唯一标识
- 会用于 cookie、localStorage、运行时内部识别
- 建议保持稳定,不要频繁改
name
- 项目展示名称
- 用于 Option 页面和页面悬浮切换器显示
enabled
- 是否启用该项目
false时该项目不会参与请求匹配
matchHosts
- 项目入口 host 列表
- 用于判断当前请求是否属于这个项目
- 支持精确匹配,例如:
local.dev:8000 - 也支持简单的
*.前缀匹配
matchPathPrefixes
- 项目入口路径前缀
- 当多个项目共用同一个 host 时,用它进一步区分项目
- 例如:
["/admin"]
configPath
- 当前项目的运行时配置接口路径
- 插件会在这个路径返回同源 JSON 配置
- 例如:
/__env_config__
ui.reloadOnApiSwitch
- 切换服务端环境后是否自动刷新页面
true:切换后立刻刷新false:只更新选择状态,不自动刷新
frontendTargets
- 前端环境列表
- 当请求没有命中任何
routeGroups[].prefixes时,会走这里选中的目标 - 页面、静态资源、其他非内部前缀请求都会使用这里的当前选择
每个 frontendTargets[] 项字段:
key- 当前前端环境唯一标识
label- 页面上展示的名称
color- 悬浮切换器里显示的小圆点颜色
target- 实际要转发到的前端地址
- 例如:
http://127.0.0.1:8000
defaultFrontendTargetKey
- 默认前端环境 key
- 首次进入项目、还没有用户选择时会使用它
routeGroups
- 服务端接口路由分组
- 每个分组通过一组路径前缀来识别“哪些请求属于这类接口”
- 一个项目可以有多个 route group
每个 routeGroups[] 项字段:
key
- 路由分组唯一标识
- 会参与 API 环境 cookie / localStorage 的 key 生成
name
- 分组展示名
- 用于页面切换器里显示
prefixes
- 当前分组命中的路径前缀列表
- 例如:
["/api", "/gateway"] - 请求路径命中其中任意一个前缀,就会被归到该分组
defaultEnvKey
- 当前分组默认使用的环境 key
envs
- 当前分组下可切换的环境列表
每个 envs[] 项字段:
key- 环境唯一标识
label- 页面上展示的环境名称
color- 悬浮切换器显示用颜色
target- 该环境的上游地址
- 如果为空字符串,表示命中这个分组后不改写上游,直接透传原请求
路由规则说明
前端请求怎么走
如果请求属于当前项目,但路径没有命中任何 routeGroups[].prefixes:
- 使用当前选中的
frontendTarget - 把页面和静态资源转发到这个前端地址
- 如果是 HTML 页面,还会自动注入悬浮环境切换器
服务端请求怎么走
如果请求路径命中了某个 routeGroups[].prefixes:
- 先找到命中的 route group
- 再读取当前选中的环境
- 最后把请求改写到该环境的
target
当前环境从哪里读取
服务端 API 环境优先级:
- header
- query(兼容兜底)
- cookie
- 分组默认环境
前端环境优先级:
- cookie
- 默认前端环境
页面悬浮切换器
插件会在匹配到的 HTML 页面中注入一个小控件,用来切换当前项目的前端环境和服务端环境。
支持:
- 拖动移动位置
- 自动保存位置
- 显示当前前端环境 / 服务端环境
- 点击后展开环境列表
- 点击页面其他区域关闭浮层
常见使用场景
场景一:本地前端 + 多套后端接口
- 页面和静态资源走本地开发服务
/api请求可以在本地 / 测试 / 线上后端之间切换
场景二:同一个后端前缀,不同项目独立配置
project A匹配a.local.dev:8000project B匹配b.local.dev:8000- 两个项目可以共用相同的接口前缀,但切换状态互不影响
场景三:一个项目多个接口域前缀
/api-user对应一个 route group/api-order对应另一个 route group- 页面切换器中分别独立切换
二次开发
这个插件项目我是开源的,如果你有兴趣可以自行fork、二次开发,详细的资料都在项目的README.md中,欢迎阅读,为了便于国内朋友,我项目在cnb上(腾讯提供的国内代码仓库托管,ps:它不止托管,可玩的东西很多,有兴趣自己了解)
