简介这是一款面向开发与测试人员的HTTP响应模拟工具以war包形式部署在Tomcat中可在不依赖真实后端服务的前提下按URL、请求方法、请求头等条件匹配并返回预设的状态码、响应头与响应体用于前端联调、自动化测试、性能压测及异常故障模拟。资源包共45个文件包含23个class、14个jar、3个xml及war、properties、xlsx、txt等涵盖可部署程序、依赖库、配置说明与使用文档压缩包约7.25MB结构完整、开箱即用。已有883人学习下载。借助它读者可快速搭建本地模拟服务验证前端逻辑、构造预期与非预期响应、评估系统对错误状态码的处理能力从而降低测试成本、提升开发与排错效率。1. 联调被后端卡住的那三天我靠一个报文模拟工具翻了身做前端或者客户端开发的人大概都经历过这种场面接口文档写得模棱两可后端服务还在联调环境里半死不活产品经理已经坐在你旁边问“这个页面什么时候能看效果”。你手里只有一个 URL 和一段不知道对不对的 JSON 示例想验证一下空数据、超长字段、异常状态码下页面长什么样结果发现根本没法让后端给你造这些边界数据。这时候一个能自己定义 HTTP 响应状态码、响应头和响应体的报文模拟工具就是救命的。Http 请求模拟报文返回工具本质上是一个轻量级的本地 HTTP 服务你告诉它“当有人请求 /api/user 时返回 200 和这段 JSON”它就照做。它解决的不是网络请求本身而是响应内容的可控性——让你在真实后端就绪之前就能把前端逻辑、异常分支、加载态、错误提示全部跑通。适合前端工程师、测试工程师、客户端开发以及任何需要在不依赖真实服务的情况下验证 HTTP 交互的人。关键词里的“http响应模拟”“响应模拟”“报文模拟”说的都是同一件事把响应的控制权从后端手里拿过来放到自己手里。我第一次用这类工具是在一个后台管理系统的项目里列表页需要根据后端返回的total字段决定分页器显示几页。后端接口没通我本地起了一个模拟服务手动把total改成 0、1、9999十分钟就把分页组件的边界情况全测完了。如果没有这个工具我得等后端排期或者写一堆临时 mock 代码再删掉前者浪费时间后者污染代码库。这个工具的价值就在于它把“等”变成了“造”。2. 报文模拟工具的核心机制从请求匹配到响应构造2.1 它到底在做什么一个可编程的 HTTP 响应器理解这类工具最直接的方式是把它看成一个“条件反射器”。它监听本地某个端口收到 HTTP 请求后按照你预设的规则去匹配请求的路径、方法、甚至请求头匹配成功就返回你定义好的响应报文。这个响应报文包括三部分状态行如HTTP/1.1 200 OK、响应头如Content-Type: application/json、响应体如一段 JSON 字符串。和常见的 Mock.js 拦截 XHR 的方案不同报文模拟工具工作在网络层它不关心你用的是 fetch、axios 还是 XMLHttpRequest也不关心你跑在浏览器、Node.js 还是移动端模拟器里。只要请求真的发到了它监听的端口它就能响应。这意味着你可以用它来模拟跨域场景、模拟服务端重定向、模拟 401 未授权跳转这些是纯前端拦截方案做不到的。常见做法是把它作为本地开发环境的一个独立进程启动前端项目的请求基地址指向http://localhost:端口然后所有接口请求都会打到这个模拟服务上。你不需要改一行业务代码只需要在工具里配置好路由和响应内容。2.2 请求匹配的优先级路径、方法、查询参数怎么排一个容易被忽略的细节是匹配优先级。假设你配置了两条规则一条匹配/api/user另一条匹配/api/user?id1。当请求/api/user?id1进来时工具应该返回哪一条不同工具的实现不一样但常见的逻辑是精确匹配优先于模糊匹配带查询参数的规则优先于不带参数的规则。我一般会这样组织规则优先级匹配条件示例说明1方法 完整路径 查询参数GET /api/user?id1最精确用于特定用例2方法 完整路径GET /api/user通用规则覆盖大部分请求3方法 路径前缀GET /api/*兜底规则防止 4044任意方法 路径* /api/health用于健康检查等场景配置的时候把最特殊的规则放前面最通用的放后面。如果工具不支持优先级排序那就靠路径长度来判断——路径越长、参数越多越应该优先匹配。这个逻辑和 Nginx 的 location 匹配是类似的有经验的运维或后端同学应该很熟悉。2.3 响应体的动态构造让模拟数据不再是死板的静态 JSON静态 JSON 只能解决“有没有数据”的问题解决不了“数据变不变”的问题。比如测试分页你希望每次请求返回的page字段递增测试时间显示你希望createTime是当前时间。这时候就需要响应体支持动态表达式。常见的做法是在响应体里嵌入占位符或模板语法。比如{ code: 0, data: { list: [], total: {{random(0, 1000)}}, page: {{request.query.page}}, timestamp: {{now}} } }工具在返回响应前会把{{...}}替换成实际计算的值。{{random(0,1000)}}生成随机数{{request.query.page}}取请求里的查询参数{{now}}取当前时间戳。这样你就能模拟出“每次请求数据都不一样”的效果更接近真实后端的行为。参数说明random(min, max)生成指定范围内的整数request.query.xxx获取 URL 查询参数request.body.xxx获取 POST 请求体里的字段now返回 ISO 格式的当前时间。不同工具支持的函数名可能略有差异但思路是一致的。配置的时候注意如果响应体是 JSON模板替换后要保证仍然是合法 JSON否则前端解析会报错。3. 从零配一条模拟规则状态码、响应头、响应体逐项拆解3.1 启动服务与基础配置假设你已经拿到了这个工具包解压后看到一个可执行文件或一个启动脚本。常见的启动方式是在命令行里指定端口和配置文件路径# 启动模拟服务监听 3000 端口加载 rules.json 配置文件 ./http-mock --port 3000 --config ./rules.json如果没有配置文件工具通常会提供一个默认的 Web 管理界面访问http://localhost:3000就能看到规则列表。我一般会先用默认配置启动确认服务能跑起来再逐步添加规则。参数说明--port指定监听端口默认可能是 8080 或 3000看工具实现--config指定规则文件路径不指定的话可能从当前目录的mock-rules.json读取。如果启动报错“端口被占用”换一个端口就行常见做法是用lsof -i :3000查一下谁占着。3.2 定义一条返回 JSON 的规则规则文件通常是一个 JSON 数组每个元素是一条规则。下面是一条最基础的规则{ method: GET, path: /api/user/info, response: { status: 200, headers: { Content-Type: application/json; charsetutf-8, X-Custom-Header: mock-server }, body: { code: 0, message: success, data: { userId: 1001, userName: 测试用户, role: admin } } } }逻辑说明当工具收到GET /api/user/info的请求时返回状态码 200响应头里带上Content-Type和自定义头响应体是后面那段 JSON。Content-Type必须设置正确否则前端可能把 JSON 当纯文本处理导致response.json()解析失败。参数说明status可以是任意合法 HTTP 状态码200、404、500 都行headers里的键值对会原样写入响应头body如果是对象工具会自动序列化为 JSON 字符串如果是字符串则直接返回。3.3 模拟异常状态码与错误响应测试前端错误处理逻辑时你需要让接口返回 4xx 或 5xx。配置方式和上面一样只改status和body{ method: POST, path: /api/order/create, response: { status: 500, headers: { Content-Type: application/json }, body: { code: 50001, message: 服务器内部错误请稍后重试, data: null } } }这样前端在调用创建订单接口时就会收到 500 错误你可以验证 catch 分支有没有正确弹出提示、有没有把错误上报到监控系统。常见做法是给同一个路径配置多条规则用不同的查询参数区分正常和异常比如/api/order/create?mockerror返回 500不带参数返回 200。3.4 模拟超时与延迟响应有些工具支持在规则里加delay字段单位是毫秒{ method: GET, path: /api/report/export, delay: 5000, response: { status: 200, headers: { Content-Type: application/json }, body: { code: 0, data: { url: https://example.com/report.xlsx } } } }这条规则会让请求等待 5 秒才返回用来测试前端的 loading 状态、超时取消逻辑、以及用户等待时的交互反馈。参数说明delay的值根据你要模拟的场景来定一般 1000 到 10000 之间比较常用。注意不要设得太大否则调试的时候自己等得难受。3.5 验证模拟效果用 curl 和浏览器双端确认配置完规则后别急着在前端项目里试先用 curl 确认服务本身是通的# 测试 GET 请求 curl -i http://localhost:3000/api/user/info # 测试 POST 请求带请求体 curl -i -X POST http://localhost:3000/api/order/create \ -H Content-Type: application/json \ -d {productId: 1, quantity: 2}-i参数会打印响应头方便你确认Content-Type和自定义头有没有生效。如果 curl 返回的结果符合预期再去前端项目里把请求基地址改过来。常见做法是在项目的环境变量文件里加一个VITE_API_BASE_URLhttp://localhost:3000或REACT_APP_API_BASE_URLhttp://localhost:3000这样切换模拟和真实后端只需要改一个配置。4. 避坑与排查那些让我加班到凌晨的配置错误4.1 跨域问题为什么浏览器控制台一直报 CORS 错误现象前端项目请求模拟服务浏览器控制台报Access-Control-Allow-Origin缺失请求被拦截。原因模拟服务默认没有开启 CORS 支持或者只允许了特定来源。浏览器出于安全策略跨域请求必须由服务端明确允许。解决在响应头里加上Access-Control-Allow-Origin: *或者指定前端项目的域名。如果工具支持全局配置就在全局响应头里加如果不支持就在每条规则的headers里手动加。另外如果请求带自定义头或Content-Type: application/json浏览器会先发一个 OPTIONS 预检请求模拟服务需要能正确响应 OPTIONS 方法返回 204 或 200并带上Access-Control-Allow-Methods和Access-Control-Allow-Headers。4.2 路径匹配不生效请求明明发了却返回 404现象前端请求/api/user/list模拟服务返回 404但规则里明明配了这条路径。原因常见的情况有三种——路径大小写不一致/api/User/Listvs/api/user/list、末尾斜杠差异/api/user/vs/api/user、以及请求方法不匹配配的是 GET实际发的是 POST。解决先看模拟服务的日志确认它收到的实际请求路径和方法是什么。然后检查规则里的path和method是否完全一致。如果工具支持路径通配符可以用/api/user/*来兜底。我一般会在规则列表最后加一条*匹配所有路径的规则返回一个明显的 404 JSON这样至少能区分“没匹配到规则”和“服务没起来”。4.3 响应体中文乱码前端拿到的是问号或方块现象响应体里的中文在浏览器里显示为乱码或者response.json()解析出来的字符串是问号。原因响应头的Content-Type没有指定charsetutf-8或者工具默认用了ISO-8859-1编码。解决把Content-Type写成application/json; charsetutf-8或text/html; charsetutf-8。如果工具支持全局编码设置在配置文件里把默认编码改成 UTF-8。另外注意如果响应体是文件读取的确认文件本身的编码也是 UTF-8不要用 GBK 保存。4.4 动态模板不替换{{now}}原样返回了现象响应体里配置了{{now}}但前端收到的还是字符串{{now}}没有被替换成时间。原因模板替换功能没有开启或者模板语法写错了。有些工具要求模板放在特定字段里或者需要用不同的分隔符。解决先查工具文档确认模板语法的正确写法。常见的是{{...}}双大括号但也有用${...}或#{...}的。如果确认语法没错检查是不是在响应体里用了 JSON 字符串而不是 JSON 对象——有些工具只对对象类型的 body 做模板替换字符串类型的 body 会原样返回。把 body 改成对象格式再试。4.5 端口冲突启动时报 Address already in use现象启动模拟服务时提示端口被占用服务起不来。原因上一次启动的模拟服务没有正常退出进程还在后台跑着或者端口被其他程序占用了。解决用lsof -i :3000或netstat -ano | findstr 3000找到占用端口的进程kill 掉。如果不想每次都手动处理可以在启动脚本里加一个检测逻辑或者换一个不常用的端口比如 34567。我一般会在项目根目录放一个start-mock.sh里面先 kill 掉旧进程再启动新的省得每次手动查。5. 进阶技巧把模拟服务变成可复用的联调基础设施5.1 用规则分组管理多场景当项目变大规则文件会膨胀到几百条找一条规则要翻半天。这时候可以按业务模块拆分成多个文件启动时用--config指定一个目录而不是单个文件工具会自动加载目录下所有.json规则文件。常见做法是按user.json、order.json、payment.json拆分每个文件里只放对应模块的规则。如果工具不支持目录加载可以在启动脚本里用cat合并成一个临时文件再启动# 合并所有规则文件后启动 cat rules/*.json | jq -s add /tmp/merged-rules.json ./http-mock --port 3000 --config /tmp/merged-rules.jsonjq -s add会把多个 JSON 数组拼接成一个数组。这个命令需要系统里装了jq没有的话用 Python 脚本替代也行。5.2 模拟文件上传与下载测试文件上传接口时模拟服务需要能接收multipart/form-data请求并返回成功响应。配置规则时method设为 POSTpath设为上传接口路径响应体返回文件 ID 或 URL。测试下载接口时响应头里要加Content-Disposition: attachment; filenamereport.xlsx响应体返回文件内容或一个重定向地址。如果工具支持直接返回静态文件把文件放在指定目录规则里配置file字段指向文件路径即可。这样前端下载功能就能完整跑通不需要后端提供真实文件。5.3 与自动化测试集成模拟服务不仅可以手动调试用还可以集成到自动化测试流程里。在 CI 流水线中先启动模拟服务再跑前端单元测试或 E2E 测试测试用例里断言页面在特定响应下的表现。测试结束后用kill命令停掉模拟服务。# CI 脚本示例 ./http-mock --port 3000 --config ./mock/rules.json MOCK_PID$! sleep 2 # 等待服务启动 npm run test:e2e kill $MOCK_PID让服务在后台运行$!拿到进程 ID测试结束后 kill 掉。sleep 2是给服务启动留时间如果机器慢可以改成 3 或 5 秒。这个模式我用了很多次比每次手动启动服务再跑测试省事得多。5.4 一个我踩过的坑规则文件热更新不生效有些工具支持修改规则文件后自动重载但实际用的时候发现改了文件没反应。后来发现是文件监听有延迟或者工具只监听启动时指定的那个文件不监听目录。解决办法是改完规则后手动重启服务或者用touch命令触发一下文件变更事件。从那以后我每次改完规则都习惯性重启一遍虽然多花几秒钟但比调试半天发现是缓存问题强。希望这些经验能帮到你少走点弯路。本文还有配套的精品资源点击获取