我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么优雅的实现前端请求Mock

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么优雅的实现前端请求Mock

这篇文章主要介绍“怎么优雅的实现前端请求Mock”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么优雅的实现前端请求Mock”文章能帮助大家解决问题。

背景

在我们前端的日常工作中,难免需要请求后端的接口获取数据来进行页面的渲染,这个时候我们前端静态页面的开发以及相应的逻辑处理都与后端的接口息息相关,所以绝大多数时候在新需求的前期,我们前后端需要统一一份接口文档,以此来作为各自开发的指导和约束。

接口定义好入参、返参之后我们就可以在前端自己mock数据进行相关的开发,比如有一个定义好的查询商品列表的接口,我们很自然的就能依据接口文档写出如下代码

// 定义api

const getProducts = ()=>{

   return axios.get('/products')

}

// 组件中使用

getProducts()。then(res=>{

    this.productList = res.data

})

但是在一开始,后端往往只是定义了一个接口格式,并没有实现其中的业务逻辑,或者是并没有部署,为了让页面有数据方便开发,我们可能会按照以下两种方式进行mock

修改定义api的部分

const getProducts = ()=>{

   return Promise.resolve([

       {id:001,name:'商品1'}

   ])

}

修改调用部分

getProducts()。then(res=>{

    // this.productList = res.data

})。finally(()=>{

    this.productList = [

       {id:001,name:'商品1'}

   ]

})

可以看出无论哪种方式,我们都要修改接口相关处的代码,等到接口真正可用时我们又得删除这一部分无用的mock代码,如果有几十个接口,重复的工作量大不说,而且容易遗漏,接下来我们就一起来尝试如何优雅实现前端mock

实践

因为目前公司项目普遍以vue为主,所以接下来的两个方案都是以vue/cli 4.x版本构建的项目进行介绍(react同理,配置webpack即可),http请求使用的主流的axios

方案一 利用axios的adpter

axios作为一款优秀的http库,能兼容在浏览器环境以及node环境发送http请求,核心就是其内置adpter模块会根据运行环境在浏览器端使用XMLHttpRequest,在node环境使用其内置http发起请求,并且支持配置自定义adpter,方案一就从这里入手

从场景出发,我们在本地开发的时候是否需要使用mock显然是一个需要全局可控的操作,可以简单的进行开关,最合适的方式就是从脚本区分

添加dev:mock脚本,区分dev,开启全局mock

// package.json

"scripts": {

    "dev": "vue-cli-service serve",

    "build": "vue-cli-service build",

    "dev:mock": "cross-env IS_MOCK=true vue-cli-service serve",

  },

cross-env帮我们处理兼容问题,向process.env中注入IS_MOCK变量

修改webpack配置,省略其余不相关配置

// vue.config.js

const IS_MOCK = process.env.IS_MOCK === 'true' // 当运行dev:mock时为true

module.exports = {

    // 利用webpack definePlugin注入全局变量

    chainWebpack: config => {

        config.plugin('define')。tap(args=>{

            args[0].IS_MOCK = IS_MOCK

            return args

        })

      },

}

添加mock配置文件

module.exports = {

    '/products':{

        code:0,

        data:[

            {id:001,name:'商品1'}

        ],

        message:'success',

    }

}

封装axios实例

import axios from "axios";

// 读取mock配置

const mockMap = require("xxxxxx/mock.js"); // mock配置文件路径

var instance = axios.create({

  adapter: (config) => {

    // mock配置中匹配到当前url并且开启mock启用自定义adpter

    if(mockMap[config.url] && IS_MOCK){

      return Promise.resolve({

        data: mockMap[config.url],

        status: 200,

      });

    }else{

        // 否则调用默认的适配器处理,需要删除自定义适配器,否则会死循环

        delete config.adapter;

        return axios(config);

    }

  },

});

export default instance

定义api采用配置后的axios实例

// api.js

import instance from 'xxxx' // axios实例路径

export const getProducts = ()=>{

    return instance.get('products')

}

组件中使用

import { getProducts } from 'api.js'

getProducts()。then(res=>{

    this.productList = res.data

})

使用这种方案后续只需要维护mock.js文件,把接口文档相应的内容配置上就可以实现本地开发请求的mock,可以运行dev或者dev:mock来决定是否启用mock

** 这种模式类似于上面修改定义api的方式实现mock,方便之处在于可以全局统一处理,实际上并不会发送http请求。

方案二 proxy + express

方案一虽然实现了简单的mock功能,但实际上思考一下还是有几处不够合理的地方:

并没有实际发送http请求,对请求的整个链路没有做到尽可能真实的模拟

依赖于axios库,其它http库能否实现以及实现是否像axios一样轻便没有探究,因此可拓展性较差

功能耦合,mock作为一个额外的功能模块,把其嵌入到axios中处理,会使得axios变得略显臃肿

基于以上几个问题,于是有了使用express启动一个代理服务器,接收我们前端应用的请求来进行mock相关的处理,模拟一个完整的http请求闭环的想法

首先在项目根目录下新建一个server.js文件,用来写我们代理服务器的代码

const express = require("express");

// 引入mock配置文件

const mockMap = require("./mock");

const app = express();

app.use(express.json());

app.all("*", requestFilter, async (req, res, next) => {

  const { path } = req;

  res.send(mockMap[path]);

});

// 端口和 webpack prxoy中设置对应上,可以随意设置一个未被占用的端口

app.listen("3306", () => {

  console.log("serve is running at port 3306");

});

通熟易懂,就是监听3306端口,拦截所有请求,返回mock数据

修改webpack的proxy配置,使得运行mock脚本时,请求打到我们的代理服务器上,省略其余不相关配置

// vue.config.js

const IS_MOCK = process.env.IS_MOCK === 'true' // 当运行dev:mock时为true

module.exports = {

    devServer: {

        // …

        proxy: {

            // 所有匹配/api的请求会被转发到target

            '/api': {

                // 开启mock时 设置target为本地代理服务地址,这里端口3306与serve中监听端口保持一致

                target: IS_MOCK ? 'http://localhost:3306/' : 'xxxxx',

                ws: true,

                changeOrigin: true,

                pathRewrite: {

                    '^/api': ''

                }

            },

        }

    },

}

修改一下上文创建axios实例的代码instance.defaults.baseURL = "/api",设置一下所有请求的baseURL,以此来使proxy配置匹配所有请求

完成上述配置,我们重启前端应用,并且启动我们的服务端代码就可以使用mock功能了

,我们可以修改一下脚本,方便当我们开启mock功能的时候自动启动serve服务

// package.json

"scripts": {

    "dev": "vue-cli-service serve",

    "build": "vue-cli-service build",

    "dev:mock": "cross-env IS_MOCK=true vue-cli-service serve & node serve.js",

  },

其实到这里,mock的功能已经可用了,我们还可以基于现有的代码结合自身的需求的进行拓展

拓展

我在项目中使用的时候进行了一点点拓展,给大家提供一个拓展的参考

修改mock配置文件

module.exports = {

    '/products':{

        code:0,

        data:[{

            id:1,

            name:'商品1'

        }],

        message:'success',

        config:{

            method:'GET',

            delay: 1000,

            validator:(request)=>{

                const error = {

                    status:400,

                    msg:'请检查参数是否合法!'

                }

                const success = {

                    status:200,

                    msg:'success'

                }

                // 假设该请求需要一个必传参数 timestamp

                return request.query.timestamp ? success : error

            },

        }

    },

}

加了额外的config字段进行一些差异化配置,例如指定响应延时 1000ms 必传参数校验等

修改serve端代码

const express = require("express");

const mockMap = require("./mock");

const app = express();

app.use(express.json());

// 请求过滤器

const requestFilter = (req, res, next) => {

  const { path,method } = req;

  // 设置相应头 处理中文乱码

  res.set('Content-Type', 'text/plain')

  // 404 提前过滤

  if (!mockMap[path]) {

    res.status(404)。end();

  }

  // 请求方法不匹配提前过滤

  if(method !== mockMap[path].config?.method ?? 'GET'){

    res.status(405)。end('请检查请求方法是否正确!')

  }

  // 自定义校验规则不匹配过滤

  if (mockMap[path].config && mockMap[path].config.validator) {

    const data = mockMap[path].config.validator(req);

    if (data.status !== 200) {

        res.status(data.status)。end(data.msg)

    }

  }

  setTimeout(() => {

    next();

  }, mockMap[path].config?.delay ?? 0);

};

app.all("*", requestFilter, async (req, res, next) => {

  const { path } = req;

  // 移除config字段

  const { code,data,message } = mockMap[path]

  res.send({code,data,message});

});

app.listen("3306", () => {

  console.log("serve is running at port 3306");

});

关于“怎么优雅的实现前端请求Mock”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么优雅的实现前端请求Mock

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

springboot接受前端请求的方法实现

本文主要介绍了springboot接受前端请求的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-01-28

react后端请求数据怎么实现

react后端请求数据的实现方法:1、在package.json中配置“ "proxy":"http://localhost:5000"”;2、在src目录下创建“setupProxy.js”文件;3、调用“setupProxy.js”中配置的功能,代码如“createProxyMiddleware('/api2',{target:...}”。
2023-05-14

springboot如何实现异步响应请求(前端请求超时的问题解决)

这篇文章主要给大家介绍了关于springboot如何实现异步响应请求(前端请求超时的问题解决)的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用springboot具有一定的参考学习价值,需要的朋友可以参考下
2023-01-30

前端不使用i18n该如何优雅的实现多语言

多语言的重要性相信不需要多言,下面这篇文章主要给大家介绍了关于前端不使用i18n该如何优雅的实现多语言,文中通过图文介绍的非常详细,需要的朋友可以参考下
2023-01-18

前端怎么用post的方式进行eventSource请求

本篇内容主要讲解“前端怎么用post的方式进行eventSource请求”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“前端怎么用post的方式进行eventSource请求”吧!1.eventS
2023-07-06

怎么使用node.js处理前端提交的GET请求

本篇内容介绍了“怎么使用node.js处理前端提交的GET请求”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、获取GET请求流程1、首先和
2023-06-17

JS前端并发多个相同的请求怎么控制为只发一个请求

这篇文章主要讲解了“JS前端并发多个相同的请求怎么控制为只发一个请求”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JS前端并发多个相同的请求怎么控制为只发一个请求”吧!描述如下同时发多个相同
2023-07-02

vue3怎么优雅的实现移动端登录注册模块

这篇文章主要介绍vue3怎么优雅的实现移动端登录注册模块,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言近期开发的移动端项目直接上了 vue3 ,新特性 composition api 确实带来了全新的开发体验.开
2023-06-14

前端HTTP发POST请求携带参数与后端接口接收参数的实现

近期在学习的时候,碰到一个关于post的小问题,故拿出来分享一下,下面这篇文章主要给大家介绍了关于前端HTTP发POST请求携带参数与后端接口接收参数的相关资料,需要的朋友可以参考下
2022-11-13

Java应用的Post请求怎么实现

这篇文章主要介绍“Java应用的Post请求怎么实现”,在日常操作中,相信很多人在Java应用的Post请求怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java应用的Post请求怎么实现”的疑惑有所
2023-06-04

Nodejs怎么实现简单的GET请求

这篇文章主要介绍了Nodejs怎么实现简单的GET请求,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。GET请求的识别非常的简单,就是URL的识别,使用的是url.parse(
2023-06-15

Qt怎么实现HTTP的Get/Post请求

本文小编为大家详细介绍“Qt怎么实现HTTP的Get/Post请求”,内容详细,步骤清晰,细节处理妥当,希望这篇“Qt怎么实现HTTP的Get/Post请求”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。借助Qt的
2023-06-30

react中axios怎么结合后端实现GET和POST请求

这篇文章主要讲解了“react中axios怎么结合后端实现GET和POST请求”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“react中axios怎么结合后端实现GET和POST请求”吧!r
2023-07-05

css中怎么优雅的实现垂直居中

这篇文章给大家分享的是有关css中怎么优雅的实现垂直居中的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言"44年前我们就把人类送上月球了,但现在我们仍然无法在 CSS 中实现垂直居中。" --Jams Ande
2023-06-08

axios gin的GET和POST请求怎么实现

今天小编给大家分享一下axios gin的GET和POST请求怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。axio
2023-06-30

编程热搜

目录