惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
V
V2EX
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
The Register - Security
The Register - Security
Recorded Future
Recorded Future
Y
Y Combinator Blog
小众软件
小众软件
Jina AI
Jina AI
V2EX - 技术
V2EX - 技术
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
宝玉的分享
宝玉的分享
The Hacker News
The Hacker News
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
博客园 - 三生石上(FineUI控件)
T
Threatpost
博客园 - 聂微东
Scott Helme
Scott Helme
IT之家
IT之家
N
Netflix TechBlog - Medium
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
MongoDB | Blog
MongoDB | Blog
T
Tor Project blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
About on SuperTechFans
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
C
Check Point Blog
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
Attack and Defense Labs
Attack and Defense Labs
T
Tailwind CSS Blog
罗磊的独立博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Webroot Blog
Webroot Blog
Help Net Security
Help Net Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest

蚊子的前端博客

微说 | 有的人觉得只要不考XX,一定能考好!-蚊子的前端博客 微说 | 春天来了-蚊子的前端博客 明天和意外不知道哪个先来-蚊子的前端博客 微说 | 既然错过了路口,就及时止损,重新规划路线上路-蚊子的前端博客 微说 | 2025年的出生人口数是792万-蚊子的前端博客 微说 | 工作年终总结,让写对接的接口的数量?-蚊子的前端博客 微说 | 温家宝:没有政治体制改革的成功 经济体制改革不可能进行到底-蚊子的前端博客 微说 | 违法犯罪了该不该被禁言?-蚊子的前端博客 微说 | 不明白为什么在推荐去俄罗斯旅游-蚊子的前端博客 微说 | 易中天论骗子-蚊子的前端博客 微说 | 一场大风吹散了秋天-蚊子的前端博客 微说 | 既要、又要、还要、更要!-蚊子的前端博客 又是一年的国庆雨季-蚊子的前端博客 微说 | 预估下2025年的出生人口数据-蚊子的前端博客 微说 | 可惜了我那些小时候的书本-蚊子的前端博客 微说 | 牛马有的是,驴不够了!-蚊子的前端博客 微说 | 能否有一条非户口也能高考的路-蚊子的前端博客 微说 | 小聊中医-蚊子的前端博客 微说 | 将要制作的一款新产品-蚊子的前端博客 微说 | 做人要有信-蚊子的前端博客 微说 | 好一个正义联盟-蚊子的前端博客 微说 | 都是见过吃过的主儿-蚊子的前端博客 微说 | 追求8小时工作制有错吗?-蚊子的前端博客 微说 | 如果尖锐的批评完全消失-蚊子的前端博客 微说 | 很好!-蚊子的前端博客 微说 | 封禁用户可以,但要告知具体原因-蚊子的前端博客 微说 | 面朝大海,春暖花开-蚊子的前端博客 微说 | 程序员的悲哀是什么?-蚊子的前端博客 微说 | 2025年出生人口的预测-蚊子的前端博客 前端在 LiveKit 中如何获取所有的参与者-蚊子的前端博客 在 Electron 中使用 LiveKit 实现屏幕共享-蚊子的前端博客 在 Electron 应用中,如何获取 Mac 的摄像头和麦克风权限-蚊子的前端博客 微说 | 不要总让台湾艺人表态-蚊子的前端博客 微说 | 他们总说要更开放-蚊子的前端博客 自己封装 uuid 踩的一个小坑-蚊子的前端博客 CKEditor5 光标在粘贴的图片下一行-蚊子的前端博客 软考出成绩了,没过-蚊子的前端博客 微说 | 也许有一天我们这个社会会进步-蚊子的前端博客 好久没有更新文章了-蚊子的前端博客 微说 | 中共中央关于进一步全面深化改革,推进中国式现代化的决定-蚊子的前端博客 微说 | 关于惩罚性赔偿-蚊子的前端博客 微说 | 生孩子是谁的事儿!-蚊子的前端博客 微说 | 给群众一些选择电视剧的空间-蚊子的前端博客 微说 | 活着-蚊子的前端博客 微说 | 借用睡前消息里面的一段话-蚊子的前端博客 微说 | 曾经梦寐以求的,现在却没了追求-蚊子的前端博客 微说 | 我小时候的那些书本-蚊子的前端博客 给博客添加了一个微说的功能-蚊子的前端博客 今年的双 11 很平静-蚊子的前端博客 微说 | 贪就是贪-蚊子的前端博客 微说 | 总有人说穿越小说为什么不发展工业和科技!-蚊子的前端博客 微说 | 花了很多时间和精力,-蚊子的前端博客 2025 年终于是增加了 2 天的假期-蚊子的前端博客 微说 | 这是我的第一条微说,-蚊子的前端博客 如何手写 Array 的 forEach 方法-蚊子的前端博客 看到聚美优品的没落,真是唏嘘-蚊子的前端博客 如何手写 Array 的 map 方法-蚊子的前端博客 秋意正浓时-蚊子的前端博客 收藏几个常用但访问比较慢的组件的官网网址-蚊子的前端博客 从 Axios 源码分析如何支持 fetch 方法的-蚊子的前端博客 1024,给博客评论区所有的头像戴上一顶可爱的帽子-蚊子的前端博客 使用 GitHub 搭建了一个静态博客-蚊子的前端博客 在 JavaScript 如何判断变量是否为空-蚊子的前端博客 我为什么还在坚持我的个人博客-蚊子的前端博客 不要再手动拼接 URL 参数,请使用 URLSearchParams-蚊子的前端博客 使用 NodeJs 向百度资源推送链接-蚊子的前端博客 工具链极度内卷,留给开发者的性能优化手段已经不多了-蚊子的前端博客 在 React 中显示多个标签,超出省略并可以 hover 显示更多-蚊子的前端博客 蚊子的前端博客:探索与分享前端技术的奇妙之旅-蚊子的前端博客 互联网程序员前景真的一片黑暗吗?-蚊子的前端博客 Deno2.0 正式发布,向 Node.js 兼容-蚊子的前端博客 React 请求数据别再使用 useEffect 和 useState,试试 SWR 吧!-蚊子的前端博客 React 的 useEffect 的一些使用场景和技巧-蚊子的前端博客 前端趣闻之 JavaScript 语言的诞生和发展-蚊子的前端博客 如何合并同一接口的相同参数的请求-蚊子的前端博客 百度搜索中关于蚊子前端博客的奇怪的检索数据-蚊子的前端博客 使用 React 实现 todo list 的 curd 操作-蚊子的前端博客 React 模板中为什么可以用逻辑与运算符-蚊子的前端博客 评论回复在一张表里的评论系统如何进行分页-蚊子的前端博客 React 组件多次调用时如何区分不同的 div 容器-蚊子的前端博客 安全赋值运算符,再也不用写 try-catch 了-蚊子的前端博客 使用 nextjs 重构我的个人博客-蚊子的前端博客 基于 gitlab 的 webhook 向飞书发通知-蚊子的前端博客 数字转换为更高量级单位的工具方法-蚊子的前端博客 如何避免旧请求的数据覆盖掉最新请求-蚊子的前端博客 JavaScript 中 toString 的冷知识-蚊子的前端博客 React 中 useState 和 useRef 与全局变量的区别-蚊子的前端博客 从面试官的角度分析下简历中存在的问题-蚊子的前端博客 使用 React 实现 6 个输入框的短信验证码功能-蚊子的前端博客 反驳那些要实时刷新页面的前端部署方案-蚊子的前端博客 JSON stringify 的一些不常见使用-蚊子的前端博客 JavaScript 中数组 Array 的常见操作-蚊子的前端博客 前端如何提升用户的交互体验-蚊子的前端博客 没有日的日期在iOS中报 Invalid Date 的探究-蚊子的前端博客 飞书很好,但还是没抗住-蚊子的前端博客 给 Antd 的 DatePicker 组件实现带有至今的功能-蚊子的前端博客 antd 的 InputNumber 输入框添加左右的加减按钮-蚊子的前端博客 给想进国央企的同学介绍一款招聘软件「国聘」-蚊子的前端博客 基于 React 和 antd 实现的图片裁剪压缩功能-蚊子的前端博客 uniapp 中 checkbox 中的 checked 不生效的方案-蚊子的前端博客
腾讯抢金达人项目中的前后端协作-蚊子的前端博客
author · 2020-01-07 · via 蚊子的前端博客

在前后端的协作过程中,通常都是并行开发的状态,那么在后端接口还没有开发完毕时,前端的业务逻辑工作就很难展开。因此也就有很多模拟接口数据的方式,这些方式各有个的优缺点:

  • 直接在代码中模拟接口数据:侵入业务逻辑,在后期需要删除这些模拟数据;
  • fiddler 替换文件:页面接口比较多时,需要替换的文件比较多;
  • fs 模块读取 json 文件:若是长列表的话,需要造的数据很多;
  • mockjs:避免上述方式的缺点,但无法校验参数是否缺失;
  • service worker:基于 service worker 可以拦截前端的请求,并构建假数据返回,但无法拦截 node 端发起的请求;
方式 校验参数合法性 切换环境方便 前后端请求均可 不修改业务代码 模拟数据方便
直接在业务代码
中写接口数据
fiddler 替换文件 yes
fs 读取 json 文件 yes yes
mockjs yes yes yes
sw yes

我们理想的状态是:

  1. 提前校验请求接口中参数的合法性,是否缺失某些参数等;
  2. 切换环境方便,既可以使用模拟数据,也可以使用测试环境中的数据,同时也可以用正式环境中的数据进行检验;
  3. 可以拦截前后端均发起的请求,并尽量少的修改业务代码;
  4. 生成的模拟数据方便,假如接口中要返回前 1000 名用户的数据,总不能在 json 文件中写 1000 条数据;

上面的这几种方式,在我们抢金达人项目中,均不适用,或者对原有逻辑改动太大,或者使用起来不方便。这里我根据我们项目的需要,基于 mockjs 并与 express 的结合,实现了一套模拟数据的方法。

1. 模拟数据并校验参数的合法性 #

把接口的数据全部写在 json 文件,然后通过 fs 模块进行读取的这种方式,在构造大量数据时非常不方便。因此我们基于 mockjs 来实现模拟的数据,几行代码就能实现排行榜等大量的模拟数据,同时,也可以模拟一些稍微极端的情况,例如用户的昵称长度过长等,这些数据在测试环境一般很少能遇到,或者在后端接口模拟的成本也会比较高。

// rank-person.js
Mock.mock({
  "rank|1000": [
    {
      "no|+1": 1,
      uin: () => Mock.Random.string(32),
      nick: () => Mock.Random.string(1, 20),
      face: () => faces[Mock.Random.integer(0, 3)],
      region: "INVALID",
      title: "初露锋芒",
      level: () => Mock.Random.integer(1, 20),
      score: () => Mock.Random.integer(1, 2000),
      winPercent: 86
    }
  ]
});

但是,纯基于 mockjs 数据的方式,我们无法提现获知接口参数的异常。当我们在匹配到接口请求后就返回数据,会降低对参数的敏感度。这里,我对配置文件进行改造,当前接口中需要的参数提前设定好,类似于 jQuery.validate 中的设定。

这里我们的排行榜接口里有个last参数,0 表示是本周的数据,1 表示是上周的数据:

module.exports = {
  params: {
    last: {
      required: true, // 是否必须
      type: "number", // 参数的类型
      defaults: 0, // 默认值
      min: 0, // 最小值
      max: 1 // 最大值等
    }
  }
};

当 mock server 接收到请求后,会先校验参数的合法性,若参数不合法直接返回。其实我们排行榜的 last 参数不是必传项,不传时即默认是 0,但我们在这里测试时改为必传,只要不传 last 参数即为参数不合法:

mock校验参数-蚊子的博客

当参数校验通过后,才会返回后面模拟的数据:

mock模拟的数据-蚊子的博客

2. 数据环境的切换 #

我们在上面的图中可以看到,当 mock 字段为"mock"时,读取模拟的数据,是不是一定要加一个 mock="mock"的参数才能去读模拟的数据呢?

这个要看咱们项目到什么状态了,当项目还在前提开发阶段时,大部分接口都还没有完成,这里我们可以将接口默认指向到模拟数据,mock="testing"时就指向到测试环境的接口;当项目已稳定上线了,在迭代更新的阶段时,大部分接口已经存在和完善了,只有部分的接口需要进行模拟调试,这时我们用mock="mock"参数来指向到模拟数据。

这里我使用 mock 参数控制,还有一个原因是,前端项目会根据当前是哪个环境,自动请求对应环境的接口,所有的接口均是统一控制的:

接口的统一配置-蚊子的博客

如上图所示,如果我们要通过环境变量控制 api 字段,最终强行修改某个接口变相请求其他环境的数据,会造成其他接口数据的混乱,最终可能的结果是页面整体会挂掉。我们在使用mock字段作为参数时,侵入的业务逻辑会维持到最小的程度,同时,也能把前后端的协作,缩小到单个接口的粒度。而且,mock 参数也只会在 local 环境生效,即使忘了去掉这个参数,也不会对线上环境造成影响。

再有,当我们前端逻辑发生变化后,除了使用模拟数据来检验,如果线上有接口,我们也想用线上的数据检验一下。可以,当传入mock="production"的参数时,mockServer 会读取线上接口的数据并返回。

3. mock 与 json #

有的同学会创建一个 json 文件,把接口需要的数据都放到这个 json 文件里,然后使用fs.readFile来读取。这样倒是也可以,但是当接口数据多的时候怎么办,例如有一个排行榜是要输出前 100 名、前 1000 名用户的数据,总不能复制出 1000 份用户的数据吧。

在当前最好的方式,就是使用 mockjs 的工具来生成数据了,可以任意的随机,也可以生成任意个数的数组数据。我们这里把对参数的校验和 mock 生成的模拟数据放到一起:

module.exports = {
  params: {
    last: {
      required: true, // 是否必须
      type: "number", // 参数的类型
      defaults: 0, // 默认值
      min: 0, // 最小值
      max: 1 // 最大值等
    }
  },
  result: {
    code: 0,
    msg: "success",
    "x-from": "mock",
    data: Mock.mock({
      "rank|100": [
        {
          "no|+1": 1,
          uin: () => Mock.Random.string(32),
          nick: () => Mock.Random.string(1, 20),
          face: () => faces[Mock.Random.integer(0, 3)],
          region: "INVALID",
          title: "初露锋芒",
          level: () => Mock.Random.integer(1, 20),
          score: () => Mock.Random.integer(1, 2000),
          winPercent: 86
        }
      ]
    })
  }
};

params 字段表示必须的参数,result 表示要返回的数据,data 中即为我们伪造的数据。

4. 实时修改模拟数据 #

我们可以在页面中直接实时修改数据,然后进行保存,自动刷新页面后,就会得到刚才想要的结果。

实时修改模拟数据-蚊子的博客

我们在页面中 mock 的接口都会在调试面板中展出来,默认调试面板时关闭的,开发者在点击页面右下角的灰色按钮后,可以呼起调试面板。修改里面的数据保存后,就实时看到刚才的效果。

5. 总结 #

在开发和后期维护的过程中,前端会经常遇到模拟接口数据的情况,要么是接口还没有开发完成,要么是接口不太好返回我们想要的状态。我也是在对比多种方案后,选择了适合当前项目的一种前后端协作方案。