你知道这样的mock吗

2022-09-19 15:08:36 浏览数 (1)

Mockjs

mock数据用过的人一定不陌生,他的好处也是层出不穷,比如下面就是一段对mockjs很好的描述:

  1. 前后端分离
  2. 不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
  3. 数据类型丰富
  4. 通过随机数据,模拟各种场景。(等等)

总结起来就是在后端接口没有开发完成之前,前端可以用已有的接口文档,在真实的请求上拦截ajax,并根据mockjs的mock数据的规则,模拟真实接口返回的数据,并将随机的模拟数据返回参与相应的数据交互处理,这样真正实现了前后台的分离开发。

类似的模拟数据有:easy mock、rap2等等。 (这里不作介绍可自行度娘) 接下来我们开始操作mock

安装及使用

这里我是基于vue来搭建项目并且使用mock. 首先当然是利用我们npm安装mock

代码语言:javascript复制
npm install mockjs 

为了让目录结构更加清晰我们可以为mock单独建立一个文件夹用来存放mockjs的模拟数据,这样便于阅读。然后需要在主入口函数(main.js)中引入该文件。

接下来就是在文件里面定义mock数据了,最常用的方法就是 Mock.mock(url, type, data)

在定义之前你需要先引入mock模块并把它缓存起来:

代码语言:javascript复制
const Mock = require('mockjs')

接下来可以开始定义数据了,这里mock他有提供自带的占位符方法 下面举几个例子:

类型1: 名字|规则: 内容

代码语言:javascript复制
Mock.mock('/test', { 'data|1-4': '哑巴' })
随机生成1到4个‘哑巴’

类型2: Mock自带模板

代码语言:javascript复制
Mock.mock('/province', '@province')
随机生成一个国内省份

类型3:根据约定规则定义数据

代码语言:javascript复制
//获取mock.Random对象
const Random = Mock.Random
//设定延迟(可选项)
Mock.setup({
  timeout: 1000
})
Mock.mock('/api',
  {
    data: {
      msg: 'success',
      code: 0,
      data: {
        //mock占位符 通过占位符引用方法 
        //随机ip
        'ip': '@ip',
        //随机url
        'url': '@url',
        //1:随机为其中一个
        "job|1": ["web", "UI", "python", "php"],
        // 1:每请求一次就会往前一位 第一次默认是第一位
        "routerName| 1": ['home', 'about', 'testTable', 'mockImg', 'calculate', 'keyboard', 'canvas'], 
        //调用方法的写法 同@email
        email: Random.email(),
      }
    }
  })

注意事项

话不多说直接上代码

代码语言:javascript复制
download() {
  //url为空的时候,ajax请求发送到当前自己的页面
  this.downloadFileByURL();
},

downloadFileByURL(url, fileName = "download") {
  this.getBlob(url).then(blob => {
    const a = document.createElement("a");
    console.log(blob);
    //mock会拦截原生ajax请求 将XMLHttpRequest 变为 MockXMLHttpRequest
    //之后会返回一个报错页面 或者 乱码(如果是文件流) 
    //所以在这一步就会报错↓↓↓↓ createObjectURL()需要接受一个对象参数
    a.href = window.URL.createObjectURL(blob);
    a.download = `${fileName}`;
    a.click();
  });
  return false;
},

getBlob(url) {
  return new Promise(resolve => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = () => {
      if (xhr.status === 200) {
        console.log(xhr,'---xhr')
        resolve(xhr.response);
      }
    };
    xhr.send();
  });
}

上面封装了一个下载文件的方法通过原生ajax请求和a标签的特性实现了下载。 这里要注意的是window.URL.createObjectURL(blob)这个方法的参数他接收的是一个对象类似这样

所以引入mock数据若是没有屏蔽出错的也是这一步,mock数据拦截了ajax请求里的一步,也就是new一个XML对象时,他会改为mockXML对象,如下图

屏蔽mock前:

屏蔽mock后:

注意这一步我调用时候没传入url,他默认是会请求当前网页。

代码语言:javascript复制
this.downloadFileByURL();

所以屏蔽mock前,返回的response会是他当前页面的html并没有返回一个blob对象,从而导致window.URL.createObjectURL(blob)这一步就报错,如果是实际中请求接口返回的文件流,那么他会将文件流直接返回给你,你打印出来看到的就是一串乱码(下图),也就是说没有屏蔽mock前通过ajax请求返回的blob类型数据他不会做处理,他拿到什么就给你什么,就导致createObjectURL(blob)传参错误。

总结

  1. 会拦截所有前端发出的HTTP请求,无论是否使用Mock.mock开启Mock仿真,都会拦截HTTP请求,这也就是为何,就算不Mock.mock也会后端无法获取前端HTTP请求的原因。因此,一旦引用mockjs的情况下,无法通过前端发出HTTP请求,而会被mockjs拦截。
  2. Mock数据无法被Network中捕获到,因为并非真实请求。

参考文章:

  1. 官方文档:https://github.com/nuysoft/Mock/wiki/Mock.Random
  2. 实例测试(可以在控制台直接mock.mock来打印数据模拟):http://mockjs.com/examples.html

0 人点赞