前端 mock 数据的几种方式
目录
接口demo
Better-mock
just mock
koa
webpack
Charles
总结
具体需求开发前,后端往往只提供接口文档,对于前端,最简单的方式就是把想要的数据写死在代码里进行开发,但这样的坏处就是和后端联调前还需要再把写死的数据从代码里删除,最好的方式是无侵入的 mock
。下边介绍几种常用的方式,大家可以结合自己的项目来选取。
大致分为三类,重写 xhr/fetch
、node.js
服务中转、系统层面拦截。
接口demo
为了后边方便的安装 node
包,可以用 webpack
进行打包,具体配置可以参考 2021年从零开发前端项目指南,看到 React
配置的前一步就够了,只需要配置一个 html
和一个接口请求。 需要注意下 webpack
的版本,不同版本后续的配置会不同,这里我用的是 5.75.0
。
最终目标是通过 mock
让下边还没有开发好的接口正常返回数据:
fetch("/api/data", {body: JSON.stringify({ id: 10 }),method: "POST",
}).then((response) => response.json()).then((json) => console.log(json));
现在肯定是 404
。
Better-mock
better-mock fork
自 Mock.js,使用方法和 Mock.js
一致,用于 javascript
mock
数据生成,它可以拦截 XHR
和 fetch
请求,并返回自定义的数据类型。
https://github.com/lavyun/better-mock
只需要在调用接口前,引入 better-mock
。
import Mock from "better-mock";// mock list 返回数组,大小是 1 到 10,对象中的 id 自动加 1
Mock.mock("/api/data", {"list|1-10": [{"id|+1": 1,},],
});fetch("/api/data", {body: JSON.stringify({ id: 10 }),method: "POST",
}).then((response) => response.json()).then((json) => console.log(json));
控制台此时就会输出数据了。
better-mock
一个好处就是可以通过它既有的语法来生成一些随机的数据,每次请求都会返回不同的数据。
坏处是会在请求发送前就拦截,导致在 Chrome
控制台就看不见请求了。
just mock
just mock 是一个浏览器插件,在代码中什么都不需要更改,只需要添加相应的接口和数据即可实现拦截。
https://just-mock.vercel.app/
插件安装好后添加相应的域名就可以拦截到相应的请求。
接着进行相应的编辑添加对应的 mock
数据就好。
这样接口就会被拦截,控制台输出预设的数据:
浏览器插件原理和 Better-mock
是一样的,但会更加轻便,无需融入到代码中。两者的原理是一样的,都是在网络请求前重写了全局的 xhr
和 fetch
,具体可以参考 油猴脚本重写fetch和xhr请求。
koa
本地通过 koa
开启一个接口服务。
// serve.js
const Koa = require("koa");
const router = require("koa-router")();
const app = new Koa();router.post("/api/data", async (ctx, next) => {ctx.response.body = {status: true,data: [1, 2, 3],msg: "获取数据成功",};
});
// add router middleware:
app.use(router.routes());app.listen(3000);
本地开启运行:node server.js
,接口提供的地址是 localhost:3000
,但是请求的地址是 loacalhost:8080
,当然可以直接修改代码里的地址为 localhost:3000
,但还可以通过 webpack
的配置,将请求转发到 localhost:3000
。
const path = require("path");
module.exports = {entry: "./src/main.js",output: {path: path.resolve(__dirname, "./dist"),filename: "bundle.js",},devServer: {static: path.resolve(__dirname, "./dist"),proxy: {// 将 /api 开头的 http 请求,都代理到 localhost:3000 上,由 koa 提供 mock 数据"/api": {target: "http://localhost:3000",secure: false,},},},
};
这样就可以看到控制台输出了:
此外,Chrome
的 Network
也可以正常看到这个请求:
这种方法也可以用来解决跨域问题,举个例子:
如果本地想访问一个具体域名的接口,比如请求知乎的热榜接口:
fetch("https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50&desktop=true",{headers: {accept: "*/*","accept-language": "zh-CN,zh;q=0.9,en;q=0.8","sec-ch-ua":'"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"',"sec-ch-ua-mobile": "?0","sec-ch-ua-platform": '"macOS"',"sec-fetch-dest": "empty","sec-fetch-mode": "cors","sec-fetch-site": "same-origin","x-ab-param": "","x-ab-pb":"CpoBCAAbAD8ARwC0AGkBagF0ATsCzALXAtgCoAOhA6IDtwOmBNYEEQVRBYsFjAWeBTAGMQbrBicHdAh2CHkI2gg/CWAJwwnECcUJxgnHCcgJyQnKCcsJzAnRCfQJBApJCmUKawqYCqUKqQq+CsQK1ArdCu0K/go7CzwLQwtGC3ELhwuNC9cL4AvlC+YLLAw4DHEMjwysDMMMyQz4DBJNAQAAAAAAAAAAAAAAAAAAAAAEAAEAAAEAAAEAAAIGAAABAAAAAAAAAAAAAAADAAAAAAEAAAABAQAAAAEAAQAAAAUCAQAABgIEAAACAAA=","x-api-version": "3.0.76","x-requested-with": "fetch","x-zse-93": "101_3_3.0","x-zse-96":"2.0_LYJSVCX+9b1YXp/sG1Azyi5tC5RpabLbkXb3w5s6rv=Gxy9uMXqMXm4LjYWRdoIz","x-zst-81":"3_2.0aR_sn77yn6O92wOB8hPZnQr0EMYxc4f18wNBUgpTQ6nxERFZfRY0-4Lm-h3_tufIwJS8gcxTgJS_AuPZNcXCTwxI78YxEM20s4PGDwN8gGcYAupMWufIoLVqr4gxrRPOI0cY7HL8qun9g93mFukyigcmebS_FwOYPRP0E4rZUrN9DDom3hnynAUMnAVPF_PhaueTF4C8IhwVIDO_8ioC0JXfW9CKpCwCs4OBQAc0uBefagCKGMo1yroBh9CKe_STVHC1IqLKHJL_chSflqHCOqgYPhYKVwH8M4Lqqq9y1wH967NC7vH80UC8wCHswgHBDgY_ovg9r0wBcJO8s9OCzcLMNgLfkgNByqCLhhUf_veOQRY_dvxmCg_zugS8iBtBFgOZkwNLDw2skTX18XSYuJLqpCYBo_pMWbS8Pv3YtGFBaqL9AwCYhbL9eGVV2rNClDL1wJLmxCgKagNBUwSqYrHBbGp8e8HGggSMQ7xC3rOs",},referrer: "https://www.zhihu.com/hot",referrerPolicy: "no-referrer-when-downgrade",body: null,method: "GET",mode: "cors",credentials: "include",}
);
由于本地域名是 http://localhost:8080/
,此时浏览器就会报跨域的错了。
此时后端可以通过 CORS
策略解决跨域的问题,但因为是测试环境,后端可能会说你自己解决吧,此时就可以通过 Koa
进行中转。
改写一下 Koa
的代码,先请求后端的接口,接着将收到的数据拿到后返回。
import Koa from "koa";
import fetch from "node-fetch";
import Router from "koa-router";const app = new Koa();
const router = new Router();
router.post("/api/data", async (ctx, next) => {const res = await fetch("https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=50&desktop=true",{headers: {accept: "*/*","accept-language": "zh-CN,zh;q=0.9,en;q=0.8","sec-ch-ua":'"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"',"sec-ch-ua-mobile": "?0","sec-ch-ua-platform": '"macOS"',"sec-fetch-dest": "empty","sec-fetch-mode": "cors","sec-fetch-site": "same-origin","x-ab-param": "","x-ab-pb":"CpoBCAAbAD8ARwC0AGkBagF0ATsCzALXAtgCoAOhA6IDtwOmBNYEEQVRBYsFjAWeBTAGMQbrBicHdAh2CHkI2gg/CWAJwwnECcUJxgnHCcgJyQnKCcsJzAnRCfQJBApJCmUKawqYCqUKqQq+CsQK1ArdCu0K/go7CzwLQwtGC3ELhwuNC9cL4AvlC+YLLAw4DHEMjwysDMMMyQz4DBJNAQAAAAAAAAAAAAAAAAAAAAAEAAEAAAEAAAEAAAIGAAABAAAAAAAAAAAAAAADAAAAAAEAAAABAQAAAAEAAQAAAAUCAQAABgIEAAACAAA=","x-api-version": "3.0.76","x-requested-with": "fetch","x-zse-93": "101_3_3.0","x-zse-96":"2.0_LYJSVCX+9b1YXp/sG1Azyi5tC5RpabLbkXb3w5s6rv=Gxy9uMXqMXm4LjYWRdoIz","x-zst-81":"3_2.0aR_sn77yn6O92wOB8hPZnQr0EMYxc4f18wNBUgpTQ6nxERFZfRY0-4Lm-h3_tufIwJS8gcxTgJS_AuPZNcXCTwxI78YxEM20s4PGDwN8gGcYAupMWufIoLVqr4gxrRPOI0cY7HL8qun9g93mFukyigcmebS_FwOYPRP0E4rZUrN9DDom3hnynAUMnAVPF_PhaueTF4C8IhwVIDO_8ioC0JXfW9CKpCwCs4OBQAc0uBefagCKGMo1yroBh9CKe_STVHC1IqLKHJL_chSflqHCOqgYPhYKVwH8M4Lqqq9y1wH967NC7vH80UC8wCHswgHBDgY_ovg9r0wBcJO8s9OCzcLMNgLfkgNByqCLhhUf_veOQRY_dvxmCg_zugS8iBtBFgOZkwNLDw2skTX18XSYuJLqpCYBo_pMWbS8Pv3YtGFBaqL9AwCYhbL9eGVV2rNClDL1wJLmxCgKagNBUwSqYrHBbGp8e8HGggSMQ7xC3rOs",},referrer: "https://www.zhihu.com/hot",referrerPolicy: "no-referrer-when-downgrade",body: null,method: "GET",mode: "cors",credentials: "include",});const data = await res.json();ctx.response.body = {status: true,data,msg: "获取数据成功",};
});
app.use(router.routes());app.listen(3000);
此时还是请求 /api/data
。
fetch("/api/data", {body: JSON.stringify({ id: 10 }),method: "POST",
}).then((response) => response.json()).then((json) => console.log(json));
依旧让 Webpack
将数据转发到 Koa
。
devServer: {static: path.resolve(__dirname, "./dist"),proxy: {// 将 `/api` 开头的 http 请求,都代理到 `localhost:3000` 上,由 koa 提供 mock 数据"/api": {target: "http://localhost:3000",secure: false,},},},
现在控制台输出的就是知乎返回的数据了,跨域问题也消失了:
当然上边解决跨域只是一个思路,具体的封装还需要结合项目来进行。
webpack
上边可以通过 webpack
进行转发数据,是因为 webpack
也启动了一个 HTTP
服务器,只不过用的不是 Koa
,是更早的一个框架 Express
,而且它们是同一个团队开发的。
既然已经有了一个 HTTP
服务器,所以也没必要再开启另一个 Koa
的了,通过给 webpack
传递一个函数,重写 Koa
返回的数据即可。
只需要通过 setupMiddlewares
重写数据即可。
const path = require("path");
module.exports = {entry: "./src/main.js",output: {path: path.resolve(__dirname, "./dist"),filename: "bundle.js",},devServer: {static: path.resolve(__dirname, "./dist"),setupMiddlewares: (middlewares, devServer) => {if (!devServer) {throw new Error("webpack-dev-server is not defined");}middlewares.unshift({path: "/api/data",middleware: (req, res) => {// mock 数据模拟接口数据res.send({ list: [1, 2, 3], msg: "webpack mock" });},});return middlewares;},},
};
此时控制台也可以看到输出的内容:
同时 Network
也是可以看到网络请求的。
Charles
终极必杀 mock
方法,因为它除了可以拦截浏览器中的请求,也可以拦截任意 App
的数据,甚至还可以拦截手机中的 HTTPS
请求,前段时间很火的羊了个羊就可以通过 Charles
抓取请求然后迅速通关。
需要注意的是 Charles
抓不到 localhost
的请求,访问的时候需要将 localhost
改为 localhost.charlesproxy.com
。
webpack
需要加一个 allowedHosts
的配置,不然会返回 Invalid Host header
。
devServer: {static: path.resolve(__dirname, "./dist"),allowedHosts: "all",
},
全部配置好后就可以看到 Charles
抓到的请求了。
此时只需要提前写好一个 json
文件,然后将右键选择 Map Local
对应的文件即可。
{"data": [1, 2, 3],"msg": "from charles"
}
接下来就可以在控制台看到 mock
成功了。
总结
几种 mock
方式各有优缺点,上边只是提供一个思路,具体的 mock
方案就需要结合项目进行一定的封装了。
相关文章:

前端 mock 数据的几种方式
目录 接口demo Better-mock just mock koa webpack Charles 总结 具体需求开发前,后端往往只提供接口文档,对于前端,最简单的方式就是把想要的数据写死在代码里进行开发,但这样的坏处就是和后端联调前还需要再把写死的数据…...
【GO】go语言入门实战 —— 猜数字游戏
文章目录 程序介绍设置随机数读取用户输入实现判断逻辑实现游戏循环完整代码 程序介绍 首先生成一个介于1~100之间的随机数,然后提示玩家输入数字,并告诉玩家是猜对了还是猜错了,如果对了程序就结束,如果错了就提醒玩家是大了还是…...

opencv-25 图像几何变换04- 透视 cv2.warpPerspective()
什么是透视? 透视是一种几何学概念,用于描述在三维空间中观察物体时,由于视角的不同而产生的变形效果。在现实世界中,当我们从不同的角度或位置观察物体时,它们会呈现出不同的形状和大小。这种现象被称为透视效果。 透…...

视频讲解Codeforces Round 887 (Div. 2)(A--C)
文章目录 A. Desorting1、板书2、代码 B. Fibonaccharsis1、板书2、代码 C. Ntarsis Set1、板书2、代码 视频讲解Codeforces Round 887 (Div. 2)(A–C) A. Desorting 1、板书 2、代码 #include<bits/stdc.h> #define endl \n #define INF 0x3f…...

【团队协作开发】将Gitee项目导入到本地IDEA中出现根目录不完整的问题解决(已解决)
前言:在团队协作开发过程中,通常我们的Gitee完整项目中会包含很多内容:后端代码、前端代码、项目结构图、项目文档等一系列资产。 将Gitee项目导入到本地IDEA中,通常会出现根目录不完整的问题。这是因为项目里面包含了后端代码、前…...
vue-pdf 单列显示多个pdf页面
<template><div><pdfv-for"i in numPages":key"i":src"src":page"i"style"display: inline-block; width: 100%"></pdf> <!-- 宽度设置100% 一行只展示一页 --></div> </template&g…...

2023年FPGA好就业吗?
FPGA岗位有哪些? 从芯片设计流程来看,FPGA岗位可以分四类 产品开发期:FPGA系统架构师 芯片设计期:数字IC设计工程师、FPGA开发工程师 芯片流片期:FPGA验证工程师 产品维护期:FAE工程师 从行业上来说&#x…...
【业务功能篇52】Springboot+mybatis mysql开启批量执行sql参数 allowMultiQueries=true
allowMultiQueriestrue参数的作用: 可以在sql语句后携带分号,实现多语句执行。可以执行批处理,同时发出多个SQL语句。 在application-xxx.xml配置文件中,配置数据库的信息 spring:datasource:dynamic:primary: mysqldb # 默认数…...

StableDiffusion 换脸实现
先看效果: 想要换的脸: 想要把脸放到的目标图片: 实现方案: StableDiffusionroop(本次实验基于roopV0.02版本) 1/安装SD,模型选择 DreamShaper,Sampler使用 Euler a 2/安装roop插件 roop插…...

直播平台源码开发提高直播质量的关键:视频编码和解码技术
在互联网日益发展的今天,直播平台成为人们互联网生活的主力军,直播平台功能的多样化与智能化使我们的生活有了极大地改变,比如短视频功能,它让我们既可以随时随地去发布自己所拍摄到的东西让世界各地的用户看到,也能让…...
如何使用 PHP 更新数据到数据库?
首先,你需要有个数据库,对吧?如果你还没有的话,可以用PHP的MySQL扩展来创建一个。不过,在此之前,你需要确保你的服务器已经安装了MySQL,并且你的PHP环境已经支持MySQL扩展。 好了,现…...
NLP masked_tokens[]、token_masks[]是什么?
1、masked_tokens[]、token_masks[]介绍 masked_tokens和token_masks两个列表用于存储mask处理后的token(分词)结果和对应的mask标志。 masked_tokens列表存储经过mask处理后的分词结果。 token_masks列表存储与每个分词结果对应的mask标志。 2、示例…...
aoa_android工程编译注意事项
1. android studio 版本 : 3.0.0 Android Studio 下载文件归档 | Android 开发者 | Android Developers (google.cn) 下载地址: https://redirector.gvt1.com/edgedl/android/studio/install/3.0.0.18/android-studio-ide-171.4408382-windows.ex…...
java篇 类的进阶0x06:可见性修饰符(访问修饰符)
文章目录 可见性修饰符(访问修饰符)成员变量都应该是 private构造方法可以是 private 的public 修饰的东西尽量不要改动非 public 的类,类名可以不和文件名相同protected 继承专属的访问控制 可见性修饰符(访问修饰符)…...

Java 贪心算法经典问题解决
文章目录 分金条题目思路代码实现测试用例以及结果输出 花费资金做项目最大收益题目思路代码实现测试用例以及结果输出 预定会议室题目思路代码实现测试用例以及结果输出 取中位数题目思路代码实现测试用例以及结果输出 最低字典序题目思路代码实现测试用例以及结果输出 结语 分…...

所有docker命令无效,解决办法
目录 ■前言 今天使用docker时,所有命令无效 ■解决办法如下 1.停止docker服务 2.查看状态 3.删除之前的docker相关的文件 4.再次查看状态 5.使用相关命令 (好用了) 6.重新下载镜像 ■前言 今天使用docker时,所有命令无…...
系列一、创建者模式
一、概述 创建者模式的主要关注点是"怎样创建对象?",它的主要特点是"将对象的创建与使用分离"。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。 二、分类 单例模式工厂方法模式抽象工厂模式原型模式建造者模式...

数据库系列:覆盖索引和规避回表
1 介绍 在MySQL数据库查询过程中,索引覆盖和避免不必要的回表,是减少检索步骤,提高执行效率的有效手段。下面从这两个角度分析如何进行MySQL检索提效。 2 数据准备 模拟一个500w数据容量的部门表 emp,表结构如下,并…...

java Spring Boot上线运维 启动jar时控制台调整零时变量
前面的文章 java 打包Spring Boot项目,并运行在windows系统中和将Spring Boot项目打包部署到阿里云linux服务器讲述了Spring Boot项目打包部署的过程 但是 这里 我们可能会遇到一种情况 此时 我们服务器 java项目占用了 80端口 但我们需要放上去一个更重要的东西&am…...
java后端校验
Java 后端数据校验 一、概述 当我们想提供可靠的 API 接口,对参数的校验,以保证最终数据入库的正确性,是 必不可少 的活。比如下图就是 我们一个项目里 新增一个菜单校验 参数的函数,写了一大堆的 if else 进行校验,…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
C#最佳实践:为何优先使用as或is而非强制转换
C#最佳实践:为何优先使用as或is而非强制转换 在 C# 的编程世界里,类型转换是我们经常会遇到的操作。就像在现实生活中,我们可能需要把不同形状的物品重新整理归类一样,在代码里,我们也常常需要将一个数据类型转换为另…...

React与原生事件:核心差异与性能对比解析
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
Java严格模式withResolverStyle解析日期错误及解决方案
在Java中使用DateTimeFormatter并启用严格模式(ResolverStyle.STRICT)时,解析日期字符串"2025-06-01"报错的根本原因是:模式字符串中的年份格式yyyy被解释为YearOfEra(纪元年份),而非…...