⚡ 一个文件搞定所有API请求和Mock服务需求 | 🎯 替代Postman的轻量级选择 | 🔒 数据本地化,安全无忧
联系我: QQ 774309635
还在为API调试工具而烦恼吗?Postman太臃肿?curl命令行太复杂?试试 WebCurl 吧!
🎉 一个8MB的二进制文件 = 完整的API测试和Mock解决方案
💡 源码极简:仅几个文件实现完整功能
| 特性 | WebCurl | Postman | curl |
|---|---|---|---|
| 安装复杂度 | ⭐ 一个文件 | ⭐⭐⭐ 需要安装 | ⭐⭐ 命令行 |
| 跨域支持 | ✅ 完美解决 | ✅ 原生支持 | ✅ 原生支持 |
| 文件大小 | 8MB | 200MB+ | 系统自带 |
| 离线使用 | ✅ 完全离线 | ❌ 需要登录 | ✅ 完全离线 |
| 数据安全 | ✅ 本地存储 | ❌ 云端同步 | ✅ 本地存储 |
| 信创兼容 | ✅ 完美支持 | ❌ 有限支持 | ✅ 完美支持 |
| IPv6支持 | ✅ 完美支持 | ✅ 支持 | ✅ 原生支持 |
| 源码简洁 | ✅ 仅4个文件 | ❌ 复杂项目 | ❌ 复杂项目 |
| 实时通信 | ✅ WebSocket+SSE | ❌ 仅HTTP | ❌ 仅HTTP |
| 调试接口 | ✅ 内置EchoServer | ❌ 需额外工具 | ❌ 需额外工具 |
| Mock服务 | ✅ 支持自定义 | ❌ 需额外工具 | ❌ 需额外工具 |
本项目是一个极致轻量、跨平台、无依赖的 HTTP 请求转发与调试工具,本质上就是一个网页版的API测试及Mock调试工具,适合接口开发、调试、测试等多种场景。
- 前端:纯原生 HTML+JS+CSS,无任何第三方库或依赖,开箱即用,加载速度极快。
- 后端:仅使用 Golang 标准库,无任何第三方依赖,安全可靠。
- 源码极简:整个项目仅包含4个文件,代码结构清晰,易于理解和维护。
- 产物:编译后仅有一个约 8M 的单一二进制文件(含前端页面),无需安装、无需环境、无需依赖,直接运行。
- 平台支持:支持 Windows、Linux、MacOS、ARM、x86_64、信创(国产芯片/操作系统)等主流及国产平台,真正做到"一次编译,到处运行"。
- 网络支持:完美支持 IPv4 和 IPv6 网络协议,适应各种网络环境。
- 实时通信:原生支持 WebSocket 和 SSE(Server-Sent Events),满足实时数据推送需求。
- 内置调试服务:集成强大的EchoServer,提供完整的请求回显和响应控制功能。
- 适用场景:接口联调、API 测试、前端跨域调试、信创环境接口测试、离线/内网环境接口调试等。
- 数据本地化存储,保障安全:所有接口信息、历史记录、变量、全局头等均仅存储于本地浏览器(localStorage),不会同步到云端或外部服务器,保障接口数据的私密性与安全性,适合企业内网、敏感环境使用。
主要用途:API 测试与调试,替代某些需要登录才能使用工具(xxxxMan,xxxFox)
- 支持多种请求体格式(form-data、x-www-form-urlencoded、json、text、xml、binary)
- 支持文件上传、下载
- 支持请求重试、超时、SSL 验证、重定向等高级选项
- 支持 WebSocket 和 SSE(Server-Sent Events)实时通信
- 内置美观易用的前端页面,支持接口历史、变量、全局头、接口集合管理
- 支持命令行参数自定义监听端口、静态目录、日志、SSL 等
- 内置EchoServer调试服务:提供完整的请求回显、响应控制、流式通信功能
- 每一个开源项目的背后,都有一群默默付出、充满激情的开发者。他们用自己的业余时间,不断地优化代码、修复bug、撰写文档,只为让项目变得更好。如果您觉得我的项目对您有所帮助,如果您认可我的努力和付出,那么请考虑给予我一点小小的打赏,友情提示:打赏不退,怕被媳妇查到大额支出🤡,如果需要技术支持,需要收费哦
项目推荐: https://github.com/o8oo8o/WebSSH 一个网页版的SSH管理工具
- 🌐 网页版 Postman 体验:无需安装客户端,浏览器即用,界面美观,功能丰富。
- 🔄 HTTP 请求转发:前端通过
/api/forward接口将请求参数提交给后端,后端代为转发并返回结果,突破浏览器跨域限制。 - 支持 HTTP CONNECT 代理隧道:支持 HTTP CONNECT 方法,可作为 HTTPS/SSH 等协议的代理隧道,适用于 curl、ssh、ncat 等工具的代理转发。
- 📁 多种请求体支持:支持
form-data(含多文件上传)、x-www-form-urlencoded、json、text、xml、binary。 - 🔧 请求头自定义:支持自定义任意请求头。
- 📤 文件上传/下载:支持多文件上传,响应内容可直接下载。
- 🔄 请求重试与超时:可配置重试次数、重试间隔、超时时间。
- 🔒 SSL 验证与重定向:可选择是否校验 SSL 证书、是否自动跟随重定向。
- 📚 前端功能丰富:接口历史、接口集合、变量替换、全局请求头、导入导出等。
- ⚙️ 命令行灵活配置:支持自定义监听地址、端口、静态目录、日志、SSL 证书等。
- ⚡ 极致轻量:单一二进制文件,体积仅约 10M,部署、迁移、分发极其方便。
- 💾 无依赖、易运维:无需数据库、无需外部依赖,直接运行。
- 🖥️ 跨平台/信创兼容:支持主流操作系统及国产软硬件平台,适合信创环境、内网、离线等特殊场景。
- 🌐 网络协议支持:完美支持 IPv4 和 IPv6 网络协议,适应各种网络环境。
- 🔌 实时通信支持:原生支持 WebSocket 和 SSE(Server-Sent Events),满足实时数据推送需求。
- 🔄 智能请求回显:自动解析并回显请求的URL、方法、请求头、请求体(文本、表单、文件、二进制等)。
- 🎛️ 灵活响应控制:支持通过自定义请求头或URL参数灵活控制响应内容和行为。
- 📊 多种响应格式:支持JSON、XML、Text等多种响应格式。
- ⏱️ 响应延迟控制:可自定义响应延迟时间,模拟网络延迟场景。
- 📥 下载响应控制:支持将响应内容作为文件下载。
- 🔌 流式通信支持:SSE和WebSocket接口支持流式数据推送。
- 🎯 自定义数据队列:支持预设响应数据,实现自定义流式推送。
- 🛡️ 健壮性保障:内置panic恢复机制,防止服务崩溃。
- 📁 完整文件服务:类似Nginx的静态文件服务器功能,支持所有常见文件类型。
- 🎨 丰富MIME支持:自动识别HTML、CSS、JS、图片、音频、视频、字体等文件类型。
- 🔒 安全防护:防止路径遍历攻击,确保文件访问安全。
- ⚡ 高性能:支持大文件传输,内置缓存控制。
- 🌍 CORS支持:内置跨域资源共享支持,适合前端开发。
- 📱 移动友好:支持移动设备访问,响应式设计。
- 支持 Web 配置:内置 Admin 控制台(默认
/mock/),在浏览器中拉取、编辑、格式化mock.json,无需改本地文件即可改配置。 - 支持 Web 热重载:在 Admin 中提交配置后,服务将新 JSON 写入文件并热重启 Mock 服务,无需手动重启进程。
- 支持 Web 启停控制:通过 Admin 的 Start / Stop / Restart 控制 Mock 服务生命周期,Admin 自身常驻,Mock 停止后仍可管理。
- 纯 JSON 配置:所有 Mock 行为由一份
mock.json定义,无代码即可增删路由、改响应、挂静态资源与 WebSocket/SSE。 - 多端口多协议监听:
listen支持多组 host/port,每组可配http与https,并支持cert_file/key_file配置 TLS。 - REST 路径参数:路由 path 支持 gorilla/mux 风格(如
/api/user/{id}),路径参数自动注入为param.*供模板与条件使用。 - 请求预匹配(match):可按 headers / query / body 配置 match 条件(headers/query 支持正则,body 支持点路径与正则),全部满足才命中路由,否则 404。
- 路由级与响应级 when:路由可配
when不满足则 403;响应可配多条when分支,按顺序匹配选一条返回,实现条件分流。 - when 表达式:when 的 value 支持等值或操作符前缀:
=、!=、>、<、~(正则)、contains,可写如"query.age": ">18"、"header.X-Role": "~^admin$"。 - 变量提取(extract):从 body/query/header 按点路径提取字段到
extract.*,供 when、响应 body/headers/cookies、模板统一使用。 - 多响应分支:单路由下可配置多条 response,每条可有自己的 when、status、headers、cookies、body、file、delay_ms,按 when 顺序命中即返回。
- 模板变量:响应 body、headers、cookies、file 路径、template 内容中支持
{{param.xxx}}、{{query.xxx}}、{{header.xxx}}、{{body.xxx}}、{{form.xxx}}、{{extract.xxx}}等命名空间。 - 强类型占位符:支持
{{@int:key}}、{{@float:key}}、{{@bool:key}},在 JSON 响应中输出数字或布尔类型而非字符串。 - 模板文件(@filename):body 或 template 可写
@payloads/xxx.json,从本地文件读取内容并做变量替换后返回,便于维护大块响应。 - 响应直接回文件:
responses[].file可指定本地文件路径(可含模板变量),直接将文件内容作为 HTTP 响应体返回。 - 响应延迟(delay_ms):可为单条 response 配置毫秒级延迟,用于模拟慢接口或超时场景。
- 响应 Cookie:支持在 response 中配置 cookies 数组(name/value/path/domain/expires/max_age/secure/http_only/same_site),值支持模板变量。
- 静态资源托管:
static可将 URL 前缀映射到本地目录,支持自定义 headers、allow_methods、download 模式(Content-Disposition: attachment)。 - CORS 预检兜底:对 OPTIONS 请求做统一 CORS 头兜底,便于前端跨域调用 Mock。
- 表单与文件上传:自动解析
multipart/form-data与application/x-www-form-urlencoded,注入form.xxx及form.xxx.filename/form.xxx.size,可在 when 与模板中使用。 - WebSocket Mock:可配置 websockets 数组,path 支持路径参数,按 script 剧本顺序执行 send、await(正则或 JSON 等值)、delay_ms、timeout_ms、close,消息内容支持模板变量。
- SSE(Server-Sent Events):可配置 sse 数组,支持 path/method/match/headers/status/cookies,events 可配 id/event/data/retry/delay_ms,data 支持模板,可选 repeat 循环推送。
- 无配置文件启动:若
mock.json不存在,以空配置{}启动,仅开放 Admin,便于首次在 Web 中编辑并保存配置。
访问 http://localhost:4444/tool 即可使用以下工具:
- JWT解析:一键解析 JWT Token,查看 Header 和 Payload 信息
- UUID生成:批量生成标准 UUID,支持一键复制
- 时间戳转换:时间戳与日期时间互转,支持秒/毫秒
- Base64编解码:文本编码/解码,支持文件转Base64、Base64转文件下载
- URL编解码:URL编码/解码,支持URL参数解析
- 正则表达式测试器:实时匹配测试,支持 g/i/m/s 标志,显示捕获组
- Hash计算:支持文本和文件的 SHA-256/SHA-1/SHA-384/SHA-512 哈希计算
- 对称加密/解密:
- 支持 AES-GCM/CBC/CTR 三种模式
- 支持 128/192/256 位密钥长度
- 支持文本和文件加密/解密
- RSA 密钥生成:生成 2048/4096 位公私钥对(PEM格式)
- RSA-OAEP 加密/解密:公钥加密、私钥解密,支持文本和小文件
- HMAC 消息认证码:支持 SHA-256/384/512,生成和验证消息认证码
- 数字签名:
- 支持 RSA-PSS、RSASSA-PKCS1-v1_5、ECDSA、Ed25519
- 生成密钥对、签名、验证
- 密钥交换:ECDH P-256/384/521、X25519,双方协商共享密钥
- 密钥派生:PBKDF2/HKDF,从密码派生加密密钥
- Token生成器:自定义长度和字符类型,生成随机 Token
- JSON格式化:JSON美化、压缩、转义/反转义
- 图片处理:
- 图片压缩(可调质量,支持 JPEG/PNG/WebP)
- 尺寸调整(支持保持宽高比)
- 图片裁剪(自定义区域)
- 录屏录像:
- 屏幕录制(支持系统音频)
- 摄像头录像(支持选择设备)
- 录制列表管理(播放/下载/删除)
- 颜色转换器:HEX/RGB/HSL 颜色互转
- 客户端信息:
- 浏览器信息(UA、平台、语言、硬件并发数等)
- 屏幕信息(分辨率、色深、像素比)
- 网络状态(网络类型、下行速度、RTT延迟)
- 媒体设备(摄像头、麦克风、扬声器)
- 电池状态(电量、充电状态)
- 服务端信息:
- 时间信息(服务器时间、客户端时间、时间差异)
- 操作系统(类型、架构、家族)
- Go运行时(版本、Goroutines、GC状态)
- CPU信息(核心数、字节序)
- 系统内存(总内存、可用内存、使用率)
- 网络接口(所有网卡信息、IP地址)
- 进程信息(PID、工作目录、执行路径)
- 用户信息(UID、GID、用户名)
- 环境变量(所有环境变量列表)
源码结构极简:
WebCurl/
├── index.html # 前端界面 WebCurl(纯原生HTML+JS+CSS)
├── main.go # 后端服务 WebCurl
├── mock.html # 前端界面 WebMock(纯原生HTML+JS+CSS)
├── mock.go # 后端服务 WebMock
├── tool.html # 前端界面 WebTools(纯原生HTML+JS+CSS)
├── ws.go # 后端服务 WebSocket
└── mux.go # 后端服务 Mux路由
# 编译
go build -o WebCurl main.go
# 也可以使用 sh build.sh 命令
# 运行(默认 0.0.0.0:4444,内嵌前端页面)
./WebCurl
# 浏览器访问
http://localhost:4444注 :构建所有平台可执行文件,请使用
sh build.sh all命令,构建完成后在build目录下查找对应平台可执行文件。
| 参数 | 说明 | 默认值 |
|---|---|---|
--host |
监听地址 | 0.0.0.0 |
--port |
监听端口 | 4444 |
--webroot |
静态文件根目录(为空用内嵌 index.html) | 空 |
--daemon |
后台运行(支持 Windows/Linux/Mac) | false |
--echo-server |
是否开启EchoServer调试服务 | true |
--log-level |
日志级别(error, info, debug) | error |
--log-file |
日志文件路径 | post_api.log |
--log-size |
日志文件大小限制(K/M/G) | 100M |
--ssl-cert |
SSL 证书文件路径 | ssl_cert.pem |
--ssl-cert-key |
SSL 证书密钥路径 | ssl_cert.key |
--upload-dir |
form-data上传文件保存目录(为空仅透传) | 空 |
--stdout-log |
是否在控制台打印日志,true为同时输出到控制台和文件,false仅输出到文件 | true |
# 默认(0.0.0.0:4444,内嵌index.html,开启EchoServer)
./WebCurl
# 指定端口和host
./WebCurl --host 127.0.0.1 --port 8888
# 指定静态目录
./WebCurl --webroot /tmp/www
# 控制日志是否输出到控制台
./WebCurl --stdout-log=false
# 开启静态文件服务器模式(指定目录)
./WebCurl --webroot /mnt/webroot
# 关闭EchoServer调试服务
./WebCurl --echo-server=false
# 后台运行(Linux/MacOS/Windows)
./WebCurl --daemon
# 组合
./WebCurl --host 0.0.0.0 --port 9000 --webroot /tmp/www --daemon --stdout-log=false
WebCurl 天生适合容器化,支持 Docker/Kubernetes 等主流云原生环境,轻松实现弹性扩展与自动化运维!
# 构建镜像
docker build -t webcurl:2.2 .
# 运行容器(默认 0.0.0.0:4444)
docker run -d -p:4444:4444 --name webcurl webcurl:2.2
# 指定数据/静态目录挂载
docker run -d --name webcurl -p 4444:4444 -v /usr/share/nginx/html/:/usr/local/WebCurl/webroot webcurl:2.2 /usr/local/WebCurl/WebCurl --webroot=/usr/local/WebCurl/webrootWebCurl 完美兼容 K8S,支持无状态部署、弹性伸缩、健康检查等企业级需求。
示例 Deployment 配置:
######################################
apiVersion: apps/v1
kind: Deployment
metadata:
name: webcurl
spec:
replicas: 1
selector:
matchLabels:
app: webcurl
template:
metadata:
labels:
app: webcurl
spec:
containers:
- name: webcurl
image: webcurl:2.2
ports:
- containerPort: 4444
# args: ["/usr/local/WebCurl/WebCurl","--echo-server=true","--port=4444"]
---
apiVersion: v1
kind: Service
metadata:
name: webcurl
spec:
type: NodePort
ports:
- port: 4444
targetPort: 4444
nodePort: 30444
selector:
app: webcurl
######################################只需
kubectl apply -f webcurl.yaml,即可在 K8s 集群中弹性部署 WebCurl!
- 极致轻量:单一二进制+极简镜像,启动快、资源占用低
- 云原生友好:无状态设计,天然适配 K8S、Docker、OpenShift 等平台
- 弹性扩展:支持副本横向扩展,轻松应对高并发
- 自动化运维:支持健康检查、日志挂载、配置注入
- 一键迁移:镜像即服务,随时随地部署到任意云/集群/本地
WebCurl,让 API 调试与测试像部署静态网站一样简单,轻松上云,随时随地,安全高效!
- 内网环境:数据不出内网,安全可控
- 信创环境:完美支持国产芯片和操作系统
- 离线部署:无网络环境也能正常使用
- 团队协作:配置可导出分享,便于团队统一
- 接口联调:前后端接口调试必备
- API测试:自动化测试前的接口验证
- 跨域调试:完美解决前端跨域问题
- 文件上传测试:支持多文件上传测试
- 接口调试:EchoServer提供完整的请求回显和响应控制
- 接口监控:定期测试关键接口状态
- 性能测试:支持重试和超时配置
- SSL测试:SSL证书验证测试
- 重定向测试:自动跟随重定向测试
- 实时通信测试:WebSocket连接和SSE事件流测试
- 网络延迟模拟:EchoServer支持响应延迟控制
- 网站托管:快速部署静态网站,支持HTML、CSS、JS等
- 文件分享:企业内部文件分享和下载服务
- 开发环境:前端开发时的本地文件服务器
- 文档服务:API文档、技术文档的在线访问
- 资源托管:图片、视频、音频等多媒体资源托管
- CDN替代:小型项目的CDN服务替代方案
启动后,浏览器访问 http://localhost:4444,即可进入 Postman 风格的调试页面。
启动后,浏览器访问 http://localhost:4444/mock,即可进入 Mock 服务器json配置页面,详细配置见下文。
- 前端会自动请求
/api/mode,如返回{ "mode": "proxy" },则所有请求将通过后端/api/forward转发,解决跨域问题。 - 否则,前端直接用 fetch 发起请求。
- 支持 GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS 等方法
- 支持多种请求体格式、文件上传、请求头自定义
- 支持变量替换、全局头、接口集合、历史记录等
- 支持请求参数、重试、超时、SSL 验证、重定向等高级选项
用于前端通过 form-data 方式提交请求参数,由后端转发到目标接口。
| 字段名 | 类型/说明 | 示例/说明 |
|---|---|---|
| url | string | 目标接口地址 |
| time_out | int | 超时时间(秒),0为不超时 |
| retry_count | int | 重试次数,0为不重试 |
| retry_delay | int | 重试间隔(秒),0为无间隔 |
| method | string | 请求方法,默认 GET |
| body_type | string | 请求体类型,见下表 |
| headers | json字符串 | [{"name":"X-Token","value":"abc"}] |
| file_info | json字符串 | [{"field_name":"files","file_name":"a.txt"}] |
| files | 文件 | 支持多文件上传 |
| body | string | 请求体内容(json/xml/text等) |
| verify_ssl | Y/N | 是否校验SSL,默认Y |
| follow_redirect | Y/N | 是否自动跟随重定向,默认Y |
form-data:多文件上传,表单参数x-www-form-urlencoded:标准表单json:application/jsontext:text/plainxml:application/xmlbinary:二进制文件上传none:无请求体
返回当前后端模式,前端据此判断是否需要通过后端转发。
返回示例
{ "mode": "proxy" }功能:智能请求回显,支持灵活的响应控制。
特性:
- 支持所有HTTP方法(GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS等)
- 自动解析并回显请求的URL、方法、请求头、请求体
- 支持文本、表单、文件上传、二进制等多种请求体类型
- 支持通过自定义请求头或URL参数灵活控制响应
响应控制参数:
| 请求头 | 作用 | 示例值 |
|---|---|---|
| X-Response-Status-Code | 控制HTTP响应状态码 | 201、404、500 |
| X-Response-Location | 设置响应Location头 | https://www.qq.com |
| X-Response-Headers | 批量设置响应头(JSON字符串,键值对) | {"X-Foo":"Bar"} |
| X-Response-Type | 控制响应体格式(json/xml/text) | json、xml、text |
| X-Response-Sleep | 控制响应延迟(单位:毫秒) | 200、1000 |
| X-Response-Body | 指定Base64编码的响应body内容(优先级最高) | eyJtc2ciOiJoZWxsbyJ9 |
| X-Response-Download | 控制响应为下载,指定下载文件名 | data.txt、result.json |
参数传递方式:
- 支持请求头方式:
curl -H "X-Response-Status-Code: 202" http://localhost:4444/api/echo - 支持URL参数方式:
curl "http://localhost:4444/api/echo?X-Response-Status-Code=202" - 请求头优先级高于URL参数
基本用法示例:
# 普通请求
curl -X GET http://localhost:4444/api/echo
curl -X POST -d 'Hello World' http://localhost:4444/api/echo
# 表单与文件上传
curl -X POST -F 'text=Hello' -F 'file=@/path/to/file' http://localhost:4444/api/echo
# 控制响应状态码
curl -H "X-Response-Status-Code: 202" http://localhost:4444/api/echo
# 控制响应类型
curl -H "X-Response-Type: xml" http://localhost:4444/api/echo
curl -H "X-Response-Type: text" -d "a simple text body" http://localhost:4444/api/echo
# 控制响应延迟
curl -H "X-Response-Sleep: 500" http://localhost:4444/api/echo
# 自定义响应体(Base64编码)
curl -H "X-Response-Body: eyJtc2ciOiJoZWxsbyJ9" http://localhost:4444/api/echo
# 下载响应内容
curl -H "X-Response-Download: data.txt" http://localhost:4444/api/echo -OJ响应结构:
{
"method": "POST",
"url": "http://localhost:4444/api/echo",
"headers": [
{"key": "Content-Type", "value": "application/json"},
...
],
"body": "Hello World"
}功能:Server-Sent Events流式回显,适合前端流式消费。
特性:
- 支持所有HTTP方法
- 返回SSE流,每条消息为JSON
- 支持自定义响应参数
- 支持流式数据推送
额外参数:
X-Response-Sse-Count:SSE消息条数,默认100X-Response-Sleep:每条SSE消息间隔(毫秒),默认500
用法示例:
# 基本SSE请求
curl http://localhost:4444/api/sse/echo
# POST带body
curl -X POST -d 'Hello SSE' http://localhost:4444/api/sse/echo
# 控制SSE消息条数和间隔
curl -H "X-Response-Sse-Count: 5" -H "X-Response-Sleep: 1000" http://localhost:4444/api/sse/echo
# SSE上传文件
curl -X POST -F 'file=@/path/to/file' http://localhost:4444/api/sse/echo功能:WebSocket流式回显,适合前端WebSocket流式消费。
特性:
- 支持WebSocket协议,升级连接后推送多条消息
- 支持所有HTTP方法(WebSocket仅升级GET,其他方法通过header传递)
- 支持自定义响应参数
额外参数:
X-Response-Websocket-Count:WebSocket消息条数,默认100X-Response-Sleep:每条消息间隔(毫秒),默认500
用法示例:
# WebSocket基本请求(需WebSocket客户端)
wscat -c ws://localhost:4444/api/ws/echo
# 控制消息条数和间隔
wscat -c "ws://localhost:4444/api/ws/echo?X-Response-Websocket-Count=5&X-Response-Sleep=1000"
# WebSocket自定义响应内容(Base64)
wscat -c "ws://localhost:4444/api/ws/echo?X-Response-Body=eyJtc2ciOiJoZWxsbyB3cyJ9"POST /api/sse/set:设置SSE响应的消息队列
POST /api/ws/set:设置WebSocket响应的消息队列
功能:预设响应数据,实现自定义流式推送。
请求体格式:
[
{"value": {"v": 1, "data": "mydata"}},
{"value": {"v": 2, "data": 123}},
{"value": "mydata"},
{"value": null},
{"value": 123}
]通过请求头 X-Response-Mode 控制SSE/WS响应行为:
default(默认):原有回显逻辑,自动回显请求内容user:从预设队列中依次取出value作为响应体react:连接建立后等待用户推送数据(WebSocket专用)
用法示例:
# 设置SSE队列
curl -X POST -H "Content-Type: application/json" \
-d '[{"value":{"v":1,"data":"mydata"}}, {"value":{"v":2,"data":123}}]' \
http://localhost:4444/api/sse/set
# SSE user模式消费
curl -H "X-Response-Mode: user" http://localhost:4444/api/sse/echo
# 设置WS队列
curl -X POST -H "Content-Type: application/json" \
-d '[{"value":{"v":1,"data":"mydata"}}, {"value":{"v":2,"data":123}}]' \
http://localhost:4444/api/ws/set
# WS user模式消费
wscat -c "ws://localhost:4444/api/ws/echo?X-Response-Mode=user"功能:支持 HTTP CONNECT 方法,可作为 HTTPS/SSH 等协议的代理隧道。
- 可直接作为 curl、ssh、ncat 等工具的 HTTP 代理服务器。
- 通过 CONNECT 建立 TCP 隧道,支持 HTTPS、WebSocket、SSH 等协议的转发。
- 适合企业内网、开发测试等需要代理隧道的场景。
用法示例:
# curl 通过 HTTP 代理访问 HTTPS 站点
curl -k -x http://localhost:4444 https://www.example.com
# ssh 通过 HTTP 代理
ssh -o "ProxyCommand ncat --proxy 127.0.0.1:4444 --proxy-type http %h %p" user@host- 该功能无需额外配置,服务启动后自动支持。
- 日志中会记录 CONNECT 隧道的建立与关闭。
- 📊 接口历史:自动保存最近 50 条请求历史,支持一键加载、导入导出、清空
- 📚 接口集合:支持多集合管理,接口保存、导入导出、删除
- 🔧 变量管理:支持变量定义与替换,便于环境切换
- 🎛️ 全局请求头:支持全局头配置,自动合并到每次请求
- ⚙️ 请求配置:支持 SSL 验证、重定向、超时、重试、缓存、mode、credentials、referrerPolicy 等高级 fetch 选项
- 💾 导入导出:支持全部配置一键导入导出,便于迁移和备份
- 🪝 Hook脚本:支持前置脚本和后置脚本,可在请求发送前和响应返回后执行自定义逻辑
Hook 脚本功能允许你在请求发送前(Pre-Request)和响应返回后(Post-Response)执行自定义 JavaScript 代码,实现动态修改请求参数、提取响应数据、自动保存变量等高级功能。
在请求区域点击 "脚本" 标签页,可以看到:
- Pre-Request Hook(前置脚本):请求发送前执行
- Post-Response Hook(后置脚本):响应返回后执行
- 控制台输出:显示脚本执行日志
前置脚本在请求发送前执行,可以动态修改请求参数。
function preRequest(request) {
// request 包含以下属性:
// - url: 请求URL(可修改)
// - method: 请求方法(可修改)
// - headers: 请求头对象(可修改)
// - body: 请求体(可修改)
// - bodyType: 请求体类型
// - settings: 请求设置
// - variables: 当前所有变量(只读)
// - utils: 工具函数集
return request; // 必须返回 request 对象
}| 属性 | 类型 | 可修改 | 说明 |
|---|---|---|---|
url |
string | ✅ | 请求的完整URL |
method |
string | ✅ | HTTP方法:GET/POST/PUT/DELETE/PATCH等 |
headers |
object | ✅ | 请求头键值对对象 |
body |
string | ✅ | 请求体内容 |
bodyType |
string | ❌ | 请求体类型:none/json/text/xml/form/formdata/binary |
settings |
object | ✅ | 请求配置:timeout、retry_count等 |
variables |
object | ❌ | 当前所有启用的变量 |
utils |
object | ❌ | 工具函数集(详见下文) |
示例1:动态添加时间戳签名
function preRequest(request) {
const timestamp = Date.now();
const nonce = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
// 添加签名相关请求头
request.headers['X-Timestamp'] = timestamp;
request.headers['X-Nonce'] = nonce;
request.headers['X-Signature'] = 'your_sign_algorithm_here';
request.utils.log('签名已生成');
return request;
}示例2:动态Token注入
function preRequest(request) {
// 从变量中获取token
const token = request.utils.getVariable('auth_token');
if (token) {
request.headers['Authorization'] = 'Bearer ' + token;
request.utils.log('已注入Token:', token.substring(0, 20) + '...');
} else {
request.utils.warn('未找到auth_token变量,请先登录');
}
return request;
}示例3:环境切换
function preRequest(request) {
const env = request.utils.getVariable('current_env') || 'dev';
const baseUrls = {
dev: 'http://localhost:8080',
test: 'http://test.example.com',
prod: 'https://api.example.com'
};
const baseUrl = baseUrls[env] || baseUrls.dev;
// 替换URL中的占位符
request.url = request.url.replace('{{base_url}}', baseUrl);
request.utils.log('当前环境:', env, 'BaseURL:', baseUrl);
return request;
}示例4:修改请求体
function preRequest(request) {
if (request.body && request.bodyType === 'json') {
try {
const body = JSON.parse(request.body);
body.timestamp = Date.now();
body.clientId = 'web-app';
request.body = JSON.stringify(body);
request.utils.log('请求体已修改');
} catch (e) {
request.utils.error('JSON解析失败:', e.message);
}
}
return request;
}后置脚本在响应返回后执行,可以处理响应数据、提取变量等。
function postResponse(response) {
// response 包含以下属性:
// - status: HTTP状态码(只读)
// - statusText: 状态文本(只读)
// - headers: 响应头对象(只读)
// - body: 响应体字符串(可修改显示内容)
// - duration: 响应耗时ms(只读)
// - contentType: 内容类型(只读)
// - json: JSON解析后的对象(只读,仅JSON响应时可用)
// - utils: 工具函数集
return response; // 必须返回 response 对象
}| 属性 | 类型 | 可修改 | 说明 |
|---|---|---|---|
status |
number | ❌ | HTTP状态码:200、404、500等 |
statusText |
string | ❌ | 状态文本:OK、Not Found等 |
headers |
object | ❌ | 响应头键值对对象 |
body |
string | ✅ | 响应体内容 |
duration |
number | ❌ | 响应耗时(毫秒) |
contentType |
string | ❌ | Content-Type响应头值 |
json |
object | ❌ | JSON解析后的对象(仅当响应是JSON时) |
utils |
object | ❌ | 工具函数集(详见下文) |
示例1:自动提取并保存Token
function postResponse(response) {
const utils = response.utils;
// 检查响应是否成功
if (response.status === 200 && response.json) {
// 尝试从不同位置提取token
const token = response.json.token ||
response.json.data?.token ||
response.json.access_token ||
response.json.result?.accessToken;
if (token) {
utils.setVariable('auth_token', token);
utils.success('Token已提取并保存');
}
}
// 检测token过期
if (response.status === 401) {
utils.warn('Token可能已过期,请重新登录');
utils.setVariable('token_expired', 'true');
}
return response;
}示例2:响应日志记录
function postResponse(response) {
const utils = response.utils;
utils.info('=== 响应信息 ===');
utils.info('状态码:', response.status);
utils.info('状态文本:', response.statusText);
utils.info('响应耗时:', response.duration, 'ms');
utils.info('内容类型:', response.contentType);
if (response.json) {
utils.info('JSON数据:', JSON.stringify(response.json, null, 2));
} else if (response.body) {
utils.info('响应体长度:', response.body.length, '字符');
}
return response;
}示例3:自动保存响应字段
function postResponse(response) {
const utils = response.utils;
if (response.json && response.json.data) {
const data = response.json.data;
// 自动保存常用字段到变量
const fieldsToSave = ['id', 'userId', 'userName', 'email', 'roleId'];
fieldsToSave.forEach(field => {
if (data[field] !== undefined) {
utils.setVariable('last_' + field, data[field]);
}
});
utils.success('已自动保存响应字段到变量');
}
return response;
}示例4:错误处理与重试标记
function postResponse(response) {
const utils = response.utils;
if (response.status >= 400) {
utils.error('请求失败:', response.status);
// 保存错误信息
utils.setVariable('last_error_status', response.status);
utils.setVariable('last_error_time', new Date().toISOString());
if (response.json && response.json.message) {
utils.error('错误信息:', response.json.message);
utils.setVariable('last_error_msg', response.json.message);
}
} else {
utils.success('请求成功');
utils.setVariable('last_error_status', '');
}
return response;
}Hook 脚本中可通过 request.utils 或 response.utils 访问工具函数集。
| 函数 | 说明 | 示例 |
|---|---|---|
log(...args) |
输出普通日志(蓝色) | utils.log('消息') |
info(...args) |
输出信息日志(蓝色) | utils.info('信息') |
success(...args) |
输出成功日志(绿色) | utils.success('成功!') |
warn(...args) |
输出警告日志(黄色) | utils.warn('警告') |
error(...args) |
输出错误日志(红色) | utils.error('错误') |
| 函数 | 参数 | 返回值 | 说明 |
|---|---|---|---|
setVariable(name, value) |
name: 变量名, value: 变量值 | void | 设置变量(自动刷新变量表格) |
getVariable(name) |
name: 变量名 | string|undefined | 获取变量值(仅启用的变量) |
getAllVariables() |
无 | object | 获取所有启用的变量 |
变量操作示例:
// 设置变量
utils.setVariable('api_key', 'sk-xxx');
utils.setVariable('user_id', '12345');
// 获取变量
const apiKey = utils.getVariable('api_key');
const userId = utils.getVariable('user_id');
// 获取所有变量
const allVars = utils.getAllVariables();
// 返回: { api_key: 'sk-xxx', user_id: '12345', ... }| 函数 | 参数 | 返回值 | 说明 |
|---|---|---|---|
setGlobalHeader(name, value) |
name: 请求头名, value: 请求头值 | void | 设置全局请求头(自动刷新请求头表格) |
getGlobalHeader(name) |
name: 请求头名 | string|undefined | 获取全局请求头值(仅启用的) |
getAllGlobalHeaders() |
无 | object | 获取所有启用的全局请求头 |
全局请求头操作示例:
// 设置全局请求头
utils.setGlobalHeader('Authorization', 'Bearer token_xxx');
utils.setGlobalHeader('X-API-Key', 'key_xxx');
// 获取全局请求头
const auth = utils.getGlobalHeader('Authorization');
// 获取所有全局请求头
const allHeaders = utils.getAllGlobalHeaders();
// 返回: { Authorization: 'Bearer token_xxx', ... }// === Pre-Request Hook ===
function preRequest(request) {
const utils = request.utils;
const token = utils.getVariable('oauth_token');
const tokenExpire = utils.getVariable('token_expire_time');
const now = Date.now();
// 检查token是否存在且未过期
if (token && tokenExpire && now < parseInt(tokenExpire)) {
request.headers['Authorization'] = 'Bearer ' + token;
utils.log('使用缓存的Token');
} else {
utils.warn('Token不存在或已过期,需要重新获取');
// 可以设置标记,让后续流程处理
utils.setVariable('need_refresh_token', 'true');
}
return request;
}
// === Post-Response Hook ===
function postResponse(response) {
const utils = response.utils;
// 如果是登录接口,自动保存token
if (response.json && response.json.access_token) {
const token = response.json.access_token;
const expiresIn = response.json.expires_in || 3600;
utils.setVariable('oauth_token', token);
utils.setVariable('token_expire_time', Date.now() + expiresIn * 1000);
utils.success('Token已保存,有效期:', expiresIn, '秒');
}
// 如果返回401,清除token
if (response.status === 401) {
utils.setVariable('oauth_token', '');
utils.setVariable('token_expire_time', '');
utils.warn('Token已失效,请重新登录');
}
return response;
}// === Pre-Request Hook ===
function preRequest(request) {
const utils = request.utils;
// 获取API密钥
const appId = utils.getVariable('app_id') || 'your_app_id';
const appSecret = utils.getVariable('app_secret') || 'your_app_secret';
// 生成签名参数
const timestamp = Date.now().toString();
const nonce = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
// 简单签名示例(实际使用时建议使用更安全的算法)
const signStr = appId + timestamp + nonce + appSecret;
// 设置签名请求头
request.headers['X-App-Id'] = appId;
request.headers['X-Timestamp'] = timestamp;
request.headers['X-Nonce'] = nonce;
request.headers['X-Signature'] = signStr; // 实际使用时应该用MD5/SHA256等
utils.log('签名参数已生成');
utils.log('AppId:', appId);
utils.log('Timestamp:', timestamp);
utils.log('Nonce:', nonce);
return request;
}// === Post-Response Hook ===
function postResponse(response) {
const utils = response.utils;
let passCount = 0;
let failCount = 0;
// 断言函数
function assert(condition, message) {
if (condition) {
utils.success('✓ ' + message);
passCount++;
} else {
utils.error('✗ ' + message);
failCount++;
}
}
utils.info('===== 开始断言测试 =====');
// 状态码断言
assert(response.status === 200, `状态码应为200,实际为${response.status}`);
// 响应时间断言
assert(response.duration < 1000, `响应时间应小于1000ms,实际为${response.duration}ms`);
// JSON结构断言
if (response.json) {
assert(response.json.code !== undefined, '响应应包含code字段');
assert(response.json.code === 0, `业务码应为0,实际为${response.json.code}`);
assert(response.json.data !== undefined, '响应应包含data字段');
// 数据字段断言
if (response.json.data) {
assert(response.json.data.id !== undefined, 'data应包含id字段');
assert(typeof response.json.data.id === 'string', 'id应为字符串类型');
}
}
utils.info('===== 断言测试完成 =====');
utils.info(`通过: ${passCount}, 失败: ${failCount}`);
// 保存测试结果
utils.setVariable('test_pass_count', passCount.toString());
utils.setVariable('test_fail_count', failCount.toString());
return response;
}Hook 脚本会随接口一起保存:
- 历史记录:发送请求后,Hook 脚本会保存到历史记录中
- 接口集合:保存接口到集合时,Hook 脚本会一起保存
- 导入导出:导出配置时会包含所有 Hook 脚本
- 必须返回对象:
preRequest必须返回request,postResponse必须返回response - 异步支持:脚本支持 async/await,可以使用 Promise
- 错误处理:脚本执行出错不会影响请求,错误信息会显示在控制台
- 安全限制:脚本在浏览器沙箱中执行,无法访问敏感 API
- 变量作用域:
setVariable设置的变量可在后续请求中使用{{变量名}}引用
Mock 是一个基于 Go 的 API Mock 服务:通过一份 JSON 配置即可提供 REST 接口、静态资源、WebSocket、SSE 等能力,并支持路径参数、条件匹配、模板变量、热重载与内置 Admin 控制台。
- 各顶层字段均可为空数组。
- 推荐在 Admin 中编辑(带校验与运行态同步),也可本地编辑后通过 Reload 或重启生效。
- JSON 中数字会解析为
float64,书写布尔/整型时注意类型。
用于配置 Mock 服务监听的地址与协议。
{
"listen": [
{
"host": "0.0.0.0",
"port": 8080,
"protocols": ["http", "https"],
"cert_file": "./certs/mock.crt",
"key_file": "./certs/mock.key"
}
]
}| 字段 | 说明 |
|---|---|
host |
监听地址:localhost、127.0.0.1、::1、域名或内网 IP |
port |
端口 |
protocols |
可同时包含 http 与 https;每个 listen 项会启动一个 Server |
cert_file / key_file |
HTTPS 证书与私钥路径;启用 https 时必填,否则启动会报错 |
将 URL 前缀映射到本地目录,用于托管 Swagger、图片、附件等。
{
"static": [
{
"mount": "/assets/",
"dir": "./public",
"download": false,
"index_files": ["index.html", "home.html"],
"allow_methods": ["GET", "HEAD"],
"headers": { "Cache-Control": "max-age=86400" }
}
]
}| 字段 | 说明 |
|---|---|
mount |
URL 前缀;不以 / 结尾时会自动补尾斜杠并做 301 重定向 |
dir |
本地目录;请求 /assets/app.js 对应 ./public/app.js |
download |
true 时所有响应带 Content-Disposition: attachment |
index_files |
目录默认首页的查找顺序(可选) |
allow_methods |
允许的 HTTP 方法,如只允许 GET/HEAD;未配置则不限制方法 |
headers |
对静态响应统一添加的头部 |
{
"method": "GET",
"path": "/api/user/{id}",
"responses": [
{ "status": 200, "body": { "id": "{{param.id}}", "ok": true } }
]
}访问 GET /api/user/42 得到:{ "id": "42", "ok": true }。
method:GET、POST、PUT、PATCH、DELETE等;配置会转为大写匹配。method: "ANY"或空字符串:不限制 HTTP 方法。path:支持 gorilla/mux 路径,如/api/user/{id}/info/{section},{id}等会注入为param.id、param.section。
在进入响应分支前,可要求 headers / query / body 同时满足条件;未配置 match 则视为通过。
"match": {
"headers": { "x-token": "^test-" },
"query": { "env": "^(dev|qa)$" },
"body": { "meta.version": "^v\\d+$", "items.0.type": "vip" }
}| 维度 | 说明 |
|---|---|
headers / query |
值为正则;若只做等值,建议写 ^value$ |
body |
键为点路径或带索引路径:foo.bar、items.0.id 或 items[0].id;值可为正则或等值(非字符串会转成字符串比较) |
全部满足才命中该 route;否则返回 404。
在 route 上可配置 when,与响应分支的 when 同语义:不通过则返回 403。
"when": {
"query.age": ">18",
"header.X-Role": "~^admin|root$"
}when 的 value 支持等值或操作符前缀:=、!=、>、<、~(正则)、contains(字符串包含)。
从请求 body/query/header 中按「点路径」提取字段,注入为 extract.<key>,供响应/模板使用。
"extract": {
"from": "body",
"rules": {
"customerId": "customer.id",
"ip": "X-Real-IP"
}
}from:body、query、header之一。rules:键为变量名,值为点路径(如customer.id、root.users.0.info.data),不要使用$.前缀。- 提取结果在模板中以
{{extract.customerId}}、{{extract.ip}}使用。
以下变量可在 when、headers、cookies、body、file、template 中使用。
| 命名空间 | 来源 | 说明 |
|---|---|---|
param.xxx |
路径参数 /foo/{id} |
mux 自动注入 |
query.xxx |
URL 查询参数 | 多值取第一个 |
header.xxx |
请求头 | 与客户端一致(大小写) |
body.xxx |
JSON 请求体顶层字段 | 嵌套需通过 extract 或 match.body 点路径 |
form.xxx |
表单字段 | multipart/form-data、application/x-www-form-urlencoded |
form.xxx.filename / form.xxx.size |
上传文件信息 | 仅 multipart 时可用 |
extract.xxx |
extract 规则结果 | 来自 extract.rules |
引用时建议带命名空间,如 {{param.id}}、{{query.env}}、{{body.name}}、{{extract.customerId}}。
除了从请求中提取变量,还支持在模板中调用内置函数,动态生成值。语法为 {{func.函数名()}} 或 {{func.函数名(参数)}}。
| 函数 | 用法 | 说明 |
|---|---|---|
uuid |
{{func.uuid()}} |
生成 UUID v4 字符串 |
timestamp |
{{func.timestamp()}} |
获取当前时间戳(秒) |
timestamp_sec |
{{func.timestamp_sec()}} |
获取当前时间戳(秒) |
timestamp_ms |
{{func.timestamp_ms()}} |
获取当前时间戳(毫秒) |
now |
{{func.now()}} |
获取当前时间,默认格式 2006-01-02 15:04:05 |
now |
{{func.now(2006-01-02)}} |
获取当前时间,自定义格式 |
date |
{{func.date()}} |
获取当前日期,默认格式 2006-01-02 |
date |
{{func.date(01/02/2006)}} |
获取当前日期,自定义格式 |
time |
{{func.time()}} |
获取当前时间,默认格式 15:04:05 |
time |
{{func.time(15:04)}} |
获取当前时间,自定义格式 |
random_int |
{{func.random_int()}} |
生成随机整数,默认范围 0-1000 |
random_int |
{{func.random_int(1, 100)}} |
生成随机整数,指定范围 |
random_string |
{{func.random_string()}} |
生成随机字符串,默认长度 16 |
random_string |
{{func.random_string(32)}} |
生成随机字符串,指定长度 |
{
"path": "/api/order/create",
"method": "POST",
"responses": [
{
"status": 200,
"headers": {
"Content-Type": "application/json",
"X-Request-Id": "{{func.uuid()}}"
},
"body": {
"code": 0,
"message": "success",
"data": {
"orderId": "{{func.uuid()}}",
"orderNo": "ORD{{func.timestamp()}}",
"createdAt": "{{func.now(2006-01-02 15:04:05)}}",
"timestamp": {{func.timestamp()}},
"token": "{{func.random_string(32)}}",
"luckyNumber": {{func.random_int(1, 100)}}
}
}
}
]
}Go 语言的时间格式使用特定的参考时间 2006-01-02 15:04:05,常用格式:
| 格式字符串 | 输出示例 |
|---|---|
2006-01-02 |
2024-01-15 |
15:04:05 |
14:30:45 |
2006-01-02 15:04:05 |
2024-01-15 14:30:45 |
2006/01/02 |
2024/01/15 |
01/02/2006 |
01/15/2024 |
20060102150405 |
20240115143045 |
responses 为数组时,按顺序匹配:每条 response 的 when 全满足则选中并返回;都不满足则使用第一条。
"responses": [
{
"when": { "param.id": "007" },
"status": 200,
"body": { "msg": "for james bond" }
},
{
"when": { "query.age": ">18" },
"headers": { "X-Adult": "true" },
"body": { "ok": true }
},
{
"status": 404,
"body": { "error": "not found" }
}
]- when:支持
param.*、query.*、header.*、body.*、extract.*、form.*;多键需全部满足。 - value 写法:
- 等值:
"param.id": "007"; - 表达式(操作符前缀):
"query.age": ">18"、"header.X-Role": "~^admin|root$"、"body.name": "contains:alice"。
支持操作符:=、!=、>、<、~(正则)、contains。
- 等值:
- 若所有分支都不满足,实现上会回退到第一条 response,因此建议最后一条写兜底。
| 字段 | 说明 |
|---|---|
status |
HTTP 状态码;可省略,默认 200 |
headers |
任意响应头;值支持模板变量 |
cookies |
Cookie 数组,见下表;会做模板替换 |
delay_ms |
延迟若干毫秒再返回,用于模拟慢接口 |
body |
字符串或对象;递归替换模板变量后输出 |
file |
本地文件路径(可含变量);直接将该文件作为响应体 |
template |
模板文件名(无需写 @);读取文件内容后做变量替换再返回 |
Cookie 配置(下划线命名):
| 字段 | 类型 | 说明 |
|---|---|---|
name / value |
string | 名称与值 |
path / domain |
string | 可选 |
expires |
string | 建议 RFC3339 |
max_age |
int | 秒 |
secure / http_only |
bool | 仅 HTTPS / 不可被 JS 读取 |
same_site |
string | lax / strict / none |
默认 {{key}} 替换为字符串。若要在 JSON 中输出数字或布尔,可使用:
{{@int:key}}→ 整型(int64){{@float:key}}→ 浮点(float64){{@bool:key}}→ 布尔
规则:
- 若整串仅为一个强类型占位符(如
"{{@int:query.age}}"),则该字段在 JSON 中为对应类型(如123、true)。 - 若与其它文字混用(如
"age={{@int:query.age}}"),则按字符串替换(如"age=77")。 - 解析失败时退化为普通字符串替换。
当 body 或 template 的值为以 @ 开头的路径时,系统会读取该文件并做 {{ }} 替换后返回。
- 示例:
"body": "@payloads/small.json",文件内容可为 JSON/XML/文本。 - 若文件不存在,响应为
"template file not found"。
- 对
multipart/form-data与application/x-www-form-urlencoded会自动解析并注入form.xxx。 - 上传文件会额外提供
form.<field>.filename、form.<field>.size。 - 可在响应或模板中引用这些变量。multipart 解析大小受
-max-multipart限制。
基于 gorilla/websocket,路径与 mux 一致,支持路径参数与模板变量。
{
"websockets": [
{
"path": "/ws/{room}",
"match": {
"query": { "token": ".+" },
"headers": { "Sec-WebSocket-Protocol": "^chat$" }
},
"script": [
{ "send": "{\"type\":\"welcome\",\"room\":\"{{param.room}}\"}" },
{ "await": { "type": "auth" }, "timeout_ms": 5000 },
{ "send": "{\"type\":\"ok\"}" },
{ "delay_ms": 1000, "send": "{\"type\":\"broadcast\"}" },
{ "close": true }
]
}
]
}| 项 | 说明 |
|---|---|
path |
与 HTTP 路由相同,可含 {param} |
match |
建立连接前校验 headers/query(支持正则);不满足则 404 |
script |
按顺序执行的动作序列 |
script 动作:
| 键 | 说明 |
|---|---|
send |
发送一条文本消息(可 JSON 字符串);支持模板变量 |
await |
阻塞等待客户端一条消息:值为字符串时按正则匹配整条文本;值为对象时按 JSON 字段等值匹配 |
timeout_ms |
与 await 配合,超时后向客户端返回错误并结束 |
delay_ms |
本动作执行前延迟(毫秒) |
close |
为 true 时发送正常关闭帧并结束脚本 |
{
"sse": [
{
"path": "/sse/{topic}",
"method": "GET",
"match": { "query": { "client": ".+" } },
"headers": { "X-Topic": "{{param.topic}}" },
"status": 200,
"cookies": [],
"events": [
{ "id": "1", "event": "hello", "data": "topic={{param.topic}}", "retry": 1500 },
{ "event": "keepalive", "data": "ping", "delay_ms": 2000 },
{ "data": "done" }
],
"repeat": false
}
]
}| 字段 | 说明 |
|---|---|
path |
路径,可含路径参数 |
method |
默认 GET,也可 POST 等 |
match |
同 route:headers/query/body 全部满足才建立流 |
headers / cookies / status |
可选;支持模板变量 |
events |
事件列表;每条可含 id、event、data、retry、delay_ms;data 支持模板 |
repeat |
true 时 events 发送完后从头循环 |
变量注入顺序(与代码一致):
- 路径参数 →
param.* - Query →
query.*,Header →header.* - 若方法允许 body,读取 JSON →
body.* - 若为表单/上传 →
form.*、form.*.filename、form.*.size - 按
extract规则 →extract.*
同一请求中,when、headers、cookies、body、file、template 共用这一套变量表。
- 地址:
http://127.0.0.1:4444/mock/ - 功能:
- 拉取配置:GET 当前
mock.json内容及服务是否运行 - Reload:POST 新配置(JSON 字符串),写入文件并热重启 Mock 服务
- Start / Stop / Restart:控制 Mock 服务进程(Admin 自身常驻,不随 Mock 停止)
- 拉取配置:GET 当前
API:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /mock/api/config |
返回 { "config": "<JSON 字符串>", "running": bool } |
| POST | /mock/api/reload |
Body:{ "config": "<完整 JSON 字符串>" },写入并重启 |
| POST | /mock/api/start / stop / restart |
启停/重启 Mock 服务 |
推荐流程:拉取配置 → 编辑/格式化 → Reload → 根据返回与日志确认是否 ok。
- 路由:gorilla/mux 逐条注册,路径参数
{id}等自动注入param.*。 - match(预过滤):
match.headers/match.query:值按正则匹配;等值请写^value$。match.body:键为点路径(含数组索引);值若为字符串则按正则,否则按字符串化后等值;全部满足才命中,否则 404。
- when(分支/路由级条件):支持
param.*、query.*、header.*、body.*、extract.*、form.*;多键全部满足才通过。value 可为等值或带操作符前缀:=、!=、>、<、~(正则)、contains;比较前会尝试数值解析(>、<)。 - extract:仅支持点路径(如
customer.id、root.users.0.info),不支持$.前缀;结果通过{{extract.<key>}}使用。 - 模板替换范围:
body、headers、cookies各字段及@模板文件内容均会替换。
- 启动时会按条输出
Register route: <METHOD> <PATH>,便于确认路由加载。 - 请求会打印路径参数注入结果(如
DEBUG param injection),便于排查模板未替换问题。 - 静态/WebSocket/SSE 注册、HTTPS 证书错误、Reload 失败等会在日志中输出。
- 长期运行建议配合 supervisor、systemd 或 Docker 做进程守护。
| 现象 | 可能原因与处理 |
|---|---|
| 命中不到路由 | 检查 method 是否与配置一致(配置会转大写);match.headers/query 正则是否过严或大小写不一致 |
| 模板没替换 | 确认使用 {{param.id}} 等带命名空间写法;确认请求中确实带对应 query/header/body;看日志中的 vars 输出 |
| when 不生效 | when 的 value 支持等值或操作符前缀(>、<、~、contains);确保 body/form/extract 已注入(正常 HTTP 已内置) |
| 返回文件 404 | responses[].file 为相对路径时相对进程工作目录;可改为与 mock.json 同目录或绝对路径;Windows 注意反斜杠 |
| WebSocket await 超时 | 确认客户端按 script 顺序发消息;可增大 timeout_ms;查看日志中的 upgrade/await 相关输出 |
| CORS 预检 | 服务对 OPTIONS 做了兜底,返回常用 CORS 头;如需定制可在响应 headers 或静态 headers 中补充 |
由于浏览器同源策略,前端直接请求第三方接口会遇到 CORS 限制。通过本工具的后端转发,前端只需请求本地服务即可,后端再代为请求目标接口,绕过跨域限制。
支持请求url,请求头,全局头替换,使用{{xxx}}引用定义的变量。
在前端选择
form-data,每个文件都可单独选择,支持多文件上传。后端会自动处理。
启动时通过
--upload-dir=/your/path参数指定目录,form-data上传的文件会自动保存到该目录(存在则覆盖)。目录需提前创建并有写权限。
在前端"请求头"标签页添加即可,支持变量替换。
只需关闭后端服务或修改
/api/mode返回内容,前端会自动切换为直连模式。
所有数据仅存储在浏览器本地(localStorage),不会上传到任何服务器。企业内网、敏感环境使用无忧。
支持Windows、Linux、MacOS、ARM架构,包括国产信创平台。一次编译,到处运行。同时完美支持IPv4和IPv6网络协议。
除了传统的HTTP/HTTPS请求,还原生支持WebSocket(双向通信)和SSE(Server-Sent Events,单向实时推送),满足各种实时通信需求。
EchoServer返回的内容相对固定,MockServer完全支持自定义,支持根据条件动态构建响应内容。
EchoServer提供完整的请求回显和响应控制功能,适合接口调试、自动化测试、网络延迟模拟等场景。支持多种响应格式和流式通信。
启动时添加
--echo-server=false参数即可关闭EchoServer调试服务。
使用
--webroot参数启动静态文件服务器模式。所有API接口将失效,变成一个纯静态文件服务器。
支持所有常见文件类型:HTML、CSS、JS、图片(PNG/JPG/GIF/SVG)、音频(MP3/WAV)、视频(MP4)、字体文件、PDF、压缩包等。会自动设置正确的MIME类型。
- 🐛 欢迎提交 issue 或 PR,完善功能和文档。
- 💡 如有建议或 bug,欢迎反馈!
MIT
如需进一步定制或有疑问,欢迎联系作者。
⭐ 如果这个项目对你有帮助,请给我们一个Star!
💬 有任何问题或建议,欢迎在GitHub上讨论!
让API调试变得简单而优雅 ✨
{ "listen": [ /* 服务监听:host/port/protocols/cert/key */ ], "static": [ /* 静态目录挂载 */ ], "routes": [ /* HTTP API Mock */ ], "websockets": [ /* WebSocket 剧本 */ ], "sse": [ /* Server-Sent Events */ ] }