阅读 754
你知道这样的mock吗

你知道这样的mock吗

Mockjs

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

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

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

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

安装及使用

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

npm install mockjs 
复制代码

为了让目录结构更加清晰我们可以为mock单独建立一个文件夹用来存放mockjs的模拟数据,这样便于阅读。然后需要在主入口函数(main.js)中引入该文件。 在这里插入图片描述 接下来就是在文件里面定义mock数据了,最常用的方法就是 Mock.mock(url, type, data) 在这里插入图片描述 在定义之前你需要先引入mock模块并把它缓存起来:

const Mock = require('mockjs')
复制代码

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

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

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

类型2: Mock自带模板

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

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

//获取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(),
      }
    }
  })
复制代码

注意事项

话不多说直接上代码

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,他默认是会请求当前网页。

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. 官方文档:github.com/nuysoft/Moc…
  2. 实例测试(可以在控制台直接mock.mock来打印数据模拟):mockjs.com/examples.ht…
文章分类
前端
文章标签