Mockjs
mock数据用过的人一定不陌生,他的好处也是层出不穷,比如下面就是一段对mockjs很好的描述:
- 前后端分离
- 不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
- 数据类型丰富
- 通过随机数据,模拟各种场景。(等等)
总结起来就是在后端接口没有开发完成之前,前端可以用已有的接口文档,在真实的请求上拦截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)
传参错误。
总结
- 会拦截所有前端发出的HTTP请求,无论是否使用Mock.mock开启Mock仿真,都会拦截HTTP请求,这也就是为何,就算不Mock.mock也会后端无法获取前端HTTP请求的原因。因此,一旦引用mockjs的情况下,无法通过前端发出HTTP请求,而会被mockjs拦截。
- Mock数据无法被Network中捕获到,因为并非真实请求。
参考文章:
- 官方文档:https://github.com/nuysoft/Mock/wiki/Mock.Random
- 实例测试(可以在控制台直接mock.mock来打印数据模拟):http://mockjs.com/examples.html