Whistle Mock流式JSON接口踩坑记:除了改Body,这个响应头不改页面直接崩

张开发
2026/4/11 3:24:18 15 分钟阅读

分享文章

Whistle Mock流式JSON接口踩坑记:除了改Body,这个响应头不改页面直接崩
Whistle Mock流式JSON接口实战避坑指南从响应头异常到完美渲染最近在重构一个实时数据监控项目时遇到了一个令人头疼的问题明明已经用Whistle成功Mock了接口返回的JSON数据页面却死活渲染不出来。控制台没有报错Network里也能看到数据返回但前端就是吃不下这口饭。经过一番折腾终于发现是content-type这个响应头在作祟。今天就把这个排查过程完整分享出来希望能帮到同样踩坑的朋友。1. 问题现象Mock成功但页面崩溃那是一个风和日丽的下午我正在为即将上线的数据看板准备Mock环境。按照常规操作流程在Whistle的Network面板中找到目标接口/api/realtime/metrics右键复制URL在Values中创建metrics-mock.json文件将准备好的测试数据粘贴进去配置规则https://example.com/api/realtime/metrics file://{metrics-mock.json}刷新页面后Network里确实显示返回了我Mock的数据{ cpu_usage: 45.2, memory_usage: 78.1, network_in: 1024, network_out: 2048 }但诡异的是前端页面就像没收到数据一样图表区域一片空白。打开控制台没有任何错误日志。这感觉就像你明明把饭端到了桌上家人却说没看见——简直让人抓狂。2. 排查过程响应头里的魔鬼细节2.1 对比真实与Mock接口的差异既然数据已经返回问题可能出在数据的包装上。我决定对比真实环境和Mock环境的接口响应真实接口响应头HTTP/1.1 200 OK Content-Type: text/event-stream;charsetUTF-8 Transfer-Encoding: chunked Connection: keep-aliveMock接口响应头HTTP/1.1 200 OK Content-Type: text/plain;charsetUTF-8 Content-Length: 132 Connection: keep-alive关键差异一目了然真实接口使用的是text/event-stream而Mock默认返回的是text/plain。这就是问题的根源2.2 为什么Content-Type如此重要流式JSON数据与普通JSON数据的区别就像自来水和瓶装水特性流式JSON (text/event-stream)普通JSON (application/json)数据传输方式持续流式传输一次性完整传输适用场景实时监控、股票行情、聊天应用普通API接口前端处理方式需要特殊的事件监听机制直接JSON.parse解析连接特性长连接服务器可主动推送短连接请求-响应模式我们的前端代码正是基于EventSourceAPI来监听数据流的const eventSource new EventSource(/api/realtime/metrics); eventSource.onmessage (event) { const data JSON.parse(event.data); updateDashboard(data); };当响应头是text/plain时EventSource根本不会触发onmessage事件导致数据虽然返回了但前端代码收不到通知。3. 完整解决方案Mock数据正确响应头3.1 配置自定义响应头在Whistle的Values中新建metrics-headers.json{ Content-Type: text/event-stream; charsetutf-8, Cache-Control: no-cache, Connection: keep-alive, Access-Control-Allow-Origin: * }3.2 更新Rules规则将Mock规则调整为两条# 设置响应头 https://example.com/api/realtime/metrics resHeaders://{metrics-headers.json} # 设置Mock数据 https://example.com/api/realtime/metrics file://{metrics-mock.json}重要提示Whistle规则是从上到下匹配的确保响应头规则在Mock数据规则之前否则可能被覆盖。3.3 验证流式数据传输刷新页面后不仅数据正常显示还能看到流式传输特有的行为Network面板中显示请求状态持续处于Pending响应类型显示为eventstream数据以SSE(Server-Sent Events)格式传输4. 高级技巧动态Mock流式数据对于需要模拟实时变化数据的场景可以结合Whistle的resScript功能// 在Values中创建metrics-script.js const data { cpu_usage: Math.random() * 100, memory_usage: 70 Math.random() * 30, network_in: 500 Math.random() * 1500, network_out: 500 Math.random() * 1500 }; exports.handleResponse (ctx, next) { ctx.setHeader(Content-Type, text/event-stream); ctx.setHeader(Cache-Control, no-cache); ctx.setHeader(Connection, keep-alive); // 模拟实时数据推送 let count 0; const timer setInterval(() { if (count 10) { clearInterval(timer); ctx.end(); return; } data.cpu_usage Math.random() * 100; data.memory_usage 70 Math.random() * 30; ctx.write(data: ${JSON.stringify(data)}\n\n); }, 1000); ctx.write(data: ${JSON.stringify(data)}\n\n); };对应规则https://example.com/api/realtime/metrics resScript://{metrics-script.js}5. 常见问题排查清单遇到Mock流式接口不工作时可以按照以下步骤检查确认响应头Content-Type是否为text/event-streamConnection是否为keep-aliveCache-Control是否设置为no-cache检查前端代码是否使用EventSource而非fetch/axios事件监听是否正确(onmessagevsaddEventListener)验证Whistle规则规则顺序是否正确响应头规则在前规则语法是否正确特别是resHeaders://和file://的用法是否有多条规则冲突数据格式验证流式数据每段应以data:开头每段数据以\n\n结尾数据应为合法JSON字符串这个项目最终上线后运行稳定但那段调试经历让我深刻认识到Mock不只是替换数据那么简单理解协议和规范同样重要。特别是在处理特殊数据格式时魔鬼往往藏在那些我们容易忽略的细节里。

更多文章