mock数据用过的人一定不陌生,他的好处也是层出不穷,比如下面就是一段对mockjs很好的描述:
总结起来就是在后端接口没有开发完成之前,前端可以用已有的接口文档,在真实的请求上拦截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': '哑巴' })
随机生成1到4个‘哑巴’
类型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)
传参错误。