Skip to Content
全部文章我的开源项目Web接口环境切换插件-whistle.env-switcher

Web接口环境切换插件-whistle.env-switcher

发布时间: 2026-03-26

whistle.env-switcher 项目简介

这是一个基于whistle(一款专门针对程序员使用的代理软件)的插件,可以做到在你开发的页面中注入一个环境切换按钮,直接页面中一键切换到本地、开发环境、测试环境、正式环境、某个同事的电脑启动的服务。

可以快速切换接口请求某个指定服务器,便于调试

在你的web中显示的效果,会在你的web中注入一个胶囊,点击后查看可选项。 1

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

1

什么是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/

1

2.安装ZeroOmega浏览器代理

为什么还需要安装浏览器代理? 因为你需要把浏览器的所有请求转发到whistle的8899端口上,否则浏览器就直接走dns解析的ip地址去了。

流量转发到你启动的whistle端口,我启动的是8083所以访问8083,你是多少就转发到多少 1

打开代理

1

这样所有的请求都会走到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

可以在插件列表看到插件了 1

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

使用配置

要代理的话需要配置,配置就是指什么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
    • 现在主要用于兼容旧链路或手工排查
  • projectHeaderKey
    • fetch / XHR 请求中携带项目标识的 header 名
  • apiEnvHeaderKey
    • fetch / 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 环境优先级:

  1. header
  2. query(兼容兜底)
  3. cookie
  4. 分组默认环境

前端环境优先级:

  1. cookie
  2. 默认前端环境

页面悬浮切换器

插件会在匹配到的 HTML 页面中注入一个小控件,用来切换当前项目的前端环境和服务端环境。

支持:

  • 拖动移动位置
  • 自动保存位置
  • 显示当前前端环境 / 服务端环境
  • 点击后展开环境列表
  • 点击页面其他区域关闭浮层

常见使用场景

场景一:本地前端 + 多套后端接口

  • 页面和静态资源走本地开发服务
  • /api 请求可以在本地 / 测试 / 线上后端之间切换

场景二:同一个后端前缀,不同项目独立配置

  • project A 匹配 a.local.dev:8000
  • project B 匹配 b.local.dev:8000
  • 两个项目可以共用相同的接口前缀,但切换状态互不影响

场景三:一个项目多个接口域前缀

  • /api-user 对应一个 route group
  • /api-order 对应另一个 route group
  • 页面切换器中分别独立切换

二次开发

这个插件项目我是开源的,如果你有兴趣可以自行fork、二次开发,详细的资料都在项目的README.md中,欢迎阅读,为了便于国内朋友,我项目在cnb上(腾讯提供的国内代码仓库托管,ps:它不止托管,可玩的东西很多,有兴趣自己了解)

仓库地址:https://cnb.cool/sojs/whistle-plugin

最后编辑于

hi