☰
JSON Server 实战指南:前端接口模拟与联调提速技巧
2026/10/7 3:28:27 网站建设 项目流程

前端开发里有个折磨人的阶段叫“联调等待”。后端接口还没写好,前端页面已经堆了一堆代码,总不能干瞪眼等接口吧?JSON Server 就是来解决这个问题的。它是一个基于 Node.js 的 mock 工具,只需要一个 JSON 文件,几十秒就能启动一个模拟的 REST API 服务,支持增删改查、过滤、排序、分页,还能自定义路由规则,甚至插入中间件模拟复杂逻辑。

这篇文章就围绕我在实际项目里的使用笔记来写,从核心原理讲到进阶玩法,再到踩坑实录,内容偏实操向,适合正在做前后端分离开发的前端新人,也适合想在团队内搭建 mock 流程的技术负责人参考。

1. 为什么前端需要 mock 数据工具

1.1 前后端并行开发的经典痛点

在前后端分离的项目里,前端和后端是并行走的。后端还在设计数据库表、调接口、修 bug,前端已经把页面切完了。这时候前端要调试页面渲染、交互逻辑、状态管理,没有接口数据就寸步难行。

我用过几种笨办法:一种是在代码里硬编码一堆假数据,写一个 data.js 丢进去;另一种是等后端接口写完再联调。硬编码的问题在于数据写死在代码里,覆盖不了真实接口的边界情况,等接上真接口还得把假数据代码删掉,删不干净还会误伤线上逻辑。等接口写完再联调就更不用说了,前端空窗期白白浪费,项目进度一拖再拖。

JSON Server 这套方案的思路就是:把数据独立成文件,用工具起一个真正的 HTTP 服务,前端代码直接通过 axios 或 fetch 请求这个服务,和后端接口的调用方式完全一致。等后端接口就绪,只要把 baseURL 换一下就行,前端代码几乎不用改。

1.2 JSON Server 的定位:一个能跑起来的假后端

JSON Server 本质上就是一个 Node.js 写的小型服务器,它把你提供的一个 JSON 文件当作数据库,根据 REST 风格自动生成接口。官方仓库的描述是“Get a full fake REST API with zero coding in less than 30 seconds”,这句话真没夸张,装完依赖、写个 JSON、敲一条命令,服务就起来了。

它的适用场景很明确:

  • 前端页面开发阶段的数据模拟
  • 原型演示和 Demo 制作
  • 前端单元测试和组件测试的接口环境
  • 后端接口尚未完成时的临时联调

不适合把它当作真正的后端使用,因为它没有权限体系,没有复杂查询引擎,数据只存在本地文件里,性能也扛不住高并发。搞清楚定位,才能在合适的场景里发挥它的价值。

2. 环境准备与基础用法

2.1 安装与启动

环境要求就一个:Node.js。建议 Node 版本 14 以上,老版本在安装最新版 JSON Server 时可能报错,我遇到过 Node 12 环境装最新版装不上的情况,后来用npx json-server临时运行才缓解,但长期使用还是要升级 Node。

安装命令:

npm install -g json-server

如果不想全局安装,也可以装成项目的开发依赖:

npm install json-server --save-dev

全局安装的好处是随时可以用,但团队协作时建议装成项目依赖,并在 package.json 的 scripts 里加一条:

"scripts": { "mock": "json-server --watch db.json --port 3000" }

这样别的同事拉到仓库,执行npm install && npm run mock就能起服务,不用每个人都装全局命令。

启动方式很简单:

json-server --watch db.json

--watch参数的意思是监听 db.json 的变化,文件一保存服务就自动重启,数据改完立刻生效。

2.2 db.json 怎么写

db.json 是 JSON Server 的数据源,结构上就是一个 JSON 对象,对象的每一个 key 对应一个资源。

{ "users": [ { "id": 1, "name": "张三", "age": 25 }, { "id": 2, "name": "李四", "age": 30 } ], "articles": [ { "id": 1, "title": "第一篇文章", "author": "张三", "published": true } ] }

启动后,/users会返回整个 users 数组,/articles会返回 articles 数组。JSON Server 会自动把数组里的对象加上 id 字段,如果你没写 id,它会自动生成自增 id。

这里有几个关键点:

  • 资源名的命名建议用小写复数,符合 REST API 的习惯
  • 数组里的每个对象建议都带 id,否则后续的增删改查操作会出问题
  • 嵌套的对象结构也能保存,比如每个 users 里带一个profile: {}对象,但注意嵌套资源的接口路径规则,后面细说

2.3 基础路由规则

JSON Server 的路由规则非常规整,基本上遵循 RESTful 风格:

请求路径作用
GET/users获取列表
GET/users/1获取单条
POST/users新增一条
PUT/users/1整体更新
PATCH/users/1局部更新
DELETE/users/1删除一条

我一开始以为 PUT 和 PATCH 差不多,实际用下来发现区别很大。PUT 是把整个对象替换掉,如果请求体里只传了name,那这个对象的age字段就会被删掉。PATCH 则是只更新请求体里带的字段,其他字段保留。前端开发时推荐优先用 PATCH,更安全。

3. 核心功能实操:过滤、排序、分页与搜索

3.1 过滤查询

JSON Server 支持以_开头的特殊查询参数,这部分是真正常用的。

http://localhost:3000/users?name=张三 http://localhost:3000/users?age=25&name=李四

上面这两种写法是基于相等条件的过滤。如果你想做范围过滤,用的是_gte、_lte、_ne、_gt、_lt:

http://localhost:3000/users?age_gte=20 http://localhost:3000/users?age_lte=30 http://localhost:3000/users?age_ne=25

这些参数的语意分别是:年龄大于等于 20、小于等于 30、不等于 25。项目里做筛选功能非常方便,不需要后端写任何逻辑,前端通过 URL 参数就能模拟出筛选效果。

还有一个需要注意的点,多个过滤条件之间的关系是 AND。我在一个项目里试过?name=张三&age=30,返回的是同时满足两个条件的记录,不是或的关系。

3.2 排序

排序用的是_sort和_order:

http://localhost:3000/users?_sort=age&_order=asc http://localhost:3000/users?_sort=age&_order=desc

多字段排序的写法:

http://localhost:3000/users?_sort=age,name&_order=desc,asc

多字段排序的顺序是,先按 age 降序,再按 name 升序。这个功能在做排行榜、列表排序类页面时特别管用。

3.3 分页

分页是列表页绕不开的需求。JSON Server 默认的实现方式有两种:

第一种是_page和_limit:

http://localhost:3000/users?_page=1&_limit=10

这个请求会返回第一页的数据,每页 10 条。响应头里会有X-Total-Count,表示总记录数,前端可以从响应头里读取这个值来计算总页数。

第二种是_start和_end,也就是切片模式:

http://localhost:3000/users?_start=0&_end=10

_start是从第几条开始取,_end是取到第几条,相当于 SQL 里的 LIMIT 和 OFFSET。这种方式适合自定义分页。

我实际开发中的体会是,如果前端用了antd或element这类组件库,分页组件通常需要 total 数量,所以一般会读取X-Total-Count响应头来做判断,而不是靠返回数据长度。

3.4 全文搜索

JSON Server 还内置了一个简单的全文搜索:

http://localhost:3000/users?q=张

q参数会在所有字段里做模糊匹配。这个功能对于简单的搜索 mock 足够用,但如果你需要精确搜索某个字段,还是用前面说的_gte、_lte或者自定义过滤更靠谱。

4. 进阶玩法:自定义路由、中间件与代码启动

4.1 自定义路由规则

基础路由满足不了所有场景。比如前端想要的路径是/api/v1/users,但 JSON Server 默认只有/users。这时需要一个routes.json文件:

{ "/api/v1/users": "/users", "/api/v1/users/:id": "/users/:id" }

启动时加载:

json-server db.json --routes routes.json

/api/v1/users请求会被转发到/users。这里面的:id是路径参数占位符,JSON Server 会自动匹配实际值。团队项目里经常用这种方式统一 mock 接口的路径风格,让前端代码在切换 mock 和真实环境时不用改路径。

4.2 使用中间件模拟业务逻辑

如果 mock 需要模拟更复杂的业务,比如登录时校验用户名密码、错误时返回特定提错误码,就需要用到中间件。

中间件本质上是一个普通的 JavaScript 函数,接收req、res、next三个参数,运行在 JSON Server 的 HTTP 处理流程中。

// middleware.js module.exports = (req, res, next) => { if (req.method === 'POST' && req.path === '/login') { const { username, password } = req.body; if (username === 'admin' && password === '123456') { res.status(200).json({ code: 0, data: { token: 'mock-token-abc' } }); } else { res.status(401).json({ code: 401, message: '用户名或密码错误' }); } return; } next(); };

启动方式:

json-server db.json --middlewares middleware.js

这样做的好处非常明显。前端在调登录接口的时候,可以验证不同账号密码的返回逻辑,比如正确的返回 token,错误的返回 401。等真实后端就绪,只需要把 mock 的 baseURL 切换掉,前端整个鉴权逻辑的分析和验证已经在这个阶段跑通了。

4.3 用 Node 代码启动 JSON Server

命令行方式够用,但如果你想在项目里通过一个脚本启动 JSON Server,或者在同一台机器上同时跑 mock 和前端开发服务器,用代码启动更方便。

// server.js const jsonServer = require('json-server'); const server = jsonServer.create(); const router = jsonServer.router('db.json'); const middlewares = jsonServer.defaults(); server.use(middlewares); server.use(jsonServer.bodyParser); server.use(router); server.listen(3000, () => { console.log('JSON Server 已启动,地址: http://localhost:3000'); });

这个方式最大的优势是灵活。你可以在启动之前挂载自己的中间件,也可以把 JSON Server 嵌入到一个 Express 应用里,专门处理某个前缀路径,其他路径交给其他服务。这样 mock 服务既是测试工具,也是整个开发环境的一部分。配合nodemon启动,改动配置文件就自动重启,体验非常好。

4.4 静态资源托管

JSON Server 还可以托管静态资源目录,比如前端打包之后的 dist 目录:

json-server db.json --static ./dist

这个功能在做纯前端演示时很有用,起一个服务能同时访问页面和 mock 接口,不用再挂 Nginx 或另起一个静态服务器。

5. 常见问题与排查技巧实录

5.1 端口被占用怎么办

最常见的问题就是端口冲突。默认端口是 3000,代码里经常会有多个项目或脚手架占用这个端口。解决办法有两个:

json-server db.json --port 4000

或者让 JSON Server 自动找空闲端口:

json-server db.json --port 0

--port 0的意思是随机选一个可用端口,启动日志里会打印实际端口。不过我建议还是显式指定端口,因为随机端口会让前端代理配置变得不稳定。

5.2 POST 请求的提交格式

使用 POST 创建数据时,一定要注意请求头的 Content-Type 必须是application/json。我之前遇到一个情况,请求发出去了,返回的却是 400 错误,排查了半天发现是 axios 默认的 Content-Type 不对,数据体没有被正确解析。

正确的 axios 写法:

axios.post('/users', { name: '王五', age: 28 }, { headers: { 'Content-Type': 'application/json' } });

JSON Server 内置了 bodyParser,只支持 JSON 格式的请求体,不支持表单格式的application/x-www-form-urlencoded。前端写习惯表单提交的同事在这里容易踩坑。

5.3 修改数据后 id 不更新的问题

当你 POST 创建一条数据时,如果请求体里没有 id,JSON Server 会基于当前数组里最大的 id 自增。但如果你手动在 db.json 里写了 id,然后 POST 时没有传 id,它会取当前最大 id 加 1,这个符合预期。

但有一个坑是:如果你删除了若干条记录,再新增一条时,JSON Server 取的是当前数组的最大 id,不是已删除记录里最大的。比如原本有 1、2、3 三条,删掉 3,新增的 id 是 3,而不是 4。这个在实际场景里通常没什么问题,但如果你后面写了依赖 id 的关联逻辑,可能就需要考虑。

5.4 中文字符编码

JSON Server 在数据修改后会重写 db.json 文件。如果数据库里有中文字符,文件保存时默认是 UTF-8,一般不会乱码。我遇到过乱码的情况是在 Windows 上使用,控制台日志显示中文正常,但文件被某些编辑器以 GBK 编码重新保存过,导致 JSON Server 解析失败。

解决办法:统一使用 UTF-8 编码保存文件,编辑器设置成无 BOM。同时,在 Windows 下启动 JSON Server,建议在 package.json 的 mock 脚本里加一句:

"mock": "chcp 65001 && json-server --watch db.json"

chcp 65001 是把控制台代码页切换到 UTF-8,可以避免中文输出乱码。

5.5 浏览器缓存导致的“没有更新”

一个容易忽略的问题:浏览器对 GET 请求有缓存,mock 数据更新了,但页面刷新后还是旧数据。

排查思路是:在请求 URL 后面加一个时间戳参数:

axios.get('/users', { params: { _t: Date.now() } });

或者在启动 JSON Server 时加一个禁用缓存的响应头。比较简单的做法是写一个中间件:

module.exports = (req, res, next) => { res.setHeader('Cache-Control', 'no-store'); next(); };

这样能保证每次请求都拿到最新的 mock 数据。这个问题在开发阶段特别容易让人误以为 JSON Server 没生效,其实是浏览器把响应缓存住了。

5.6 嵌套资源与关联数据的关系

JSON Server 支持嵌套资源的路径,比如:

{ "users": [ { "id": 1, "name": "张三", "posts": [{ "id": 1, "title": "你好" }] } ] }

访问/users/1/posts可以获取这个用户下的所有文章。但是注意,嵌套资源的写法在更新和删除时比较别扭,建议数据设计尽量扁平化,不要过度嵌套。如果你需要一个用户和一个文章列表这样的一对多关系,更推荐用独立资源加外键字段的方式,比如 posts 里带一个userId,再通过过滤查询拿到某个用户下的文章。

6. 其他实用技巧与经验总结

6.1 使用--watch的注意事项

--watch模式下的热更新确实方便,但它有个副作用:它监控的是 db.json 文件的修改事件,你如果手动改的时候保存得太频繁,或者文件被格式化工具批量处理,会导致服务反复重启。

我遇到过最烦的情况是:编辑器保存时自动格式化整个 JSON 文件,导致 JSON Server 的重启频率异常,页面接口响应时断时续。解决办法是,把--watch关掉,改成手动重启,或者在编辑器里对 db.json 关闭自动格式化。

6.2 结合前端项目使用:代理转发

在 Vite 或 Webpack 项目里,前端开发服务器有自己的端口,JSON Server 在另一个端口,直接跨域请求会有 CORS 问题。JSON Server 默认开启了 CORS,所以直接用没问题。

但如果你想保持请求路径和线上一致,通常在 vite.config.js 里配置代理:

export default { server: { proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } } };

这样前端代码里请求/api/users,开发服务器会自动转发到 JSON Server。联调真实接口时,只要改代理目标地址,代码里一个字不用动。

6.3 面试角度:mock 工具相关的高频问题

我在整理前端面试题时发现,JSON Server 经常被当成一道考察工程化能力的题目。面试官会问:“后端接口还没好,前端怎么调试?”

这个问题不是考你会不会用某个工具,而是考察你有没有完整的开发链路思维。正确的回答思路是:

  • 先说明前端 mock 的核心目标:让前端开发和测试不被后端阻塞
  • 列举主流方案:硬编码数据、Mock.js、Charles 拦截、JSON Server
  • 说明 JSON Server 的优势:纯配置即可得到 REST API,支持增删改查、分页、过滤、排序,满足绝大多数前端交互场景
  • 结合项目经验,说明如何通过中间件模拟登录鉴权、异常返回等复杂逻辑

这么回答基本就展示了你从工具使用到工程落地的完整能力。

6.4 为什么不建议在生产环境用 JSON Server

JSON Server 只是一个开发期的 mock 工具,所有人都不要把它当作真正的后端部署到线上。原因有几个:

  • 数据存储在文件中,无法支撑多实例部署
  • 没有鉴权和权限控制机制
  • 查询能力有限,无法处理复杂关联查询
  • 并发能力不足

它的职责是帮前端把开发阶段跑起来,等到联调阶段就应该切到真实接口。团队敏捷开发时,这个工具能很好地发挥桥梁作用。我自己通常会在项目里保留一份 mock 环境配置,用来做 UI 测试、演示、回归验证,但绝对不接入生产链路。

6.5 个人实操中的几点体会

用了这么久 JSON Server,我最大的感受是:它不仅仅是“造点假数据”,而是把前端从接口依赖中解放出来。以前前端开发被动等接口,现在可以先把接口结构定义好,前端按约定开发,后端按约定实现,两边反而是并行推进的。

建议你可以把 db.json 当成接口文档的“可运行版本”。后端把字段结构定义清楚,前端就按这个结构去调用和渲染;而有争议的字段或返回格式,直接在 db.json 里 mock 出来,前后端对着数据讨论,比口头说字段名清楚得多。

最后补充一点,团队协作时在 README 里写清楚 mock 服务的启动方式和对接规范,能让新同事少踩很多坑。配置文件本身不复杂,但没文档的时候出了问题,每个人的排查方向都不一样,反而浪费时间。数据文件里放几条有代表性的假数据,把边界情况也加进去,价值远超过随随便便塞几个对象。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询