手写mockjs

  目录

简单的写一个mockjs

手写mockjs

在我们前端的开发中,mock数据是必须走的一环,我们可以完全脱离后端接口,等我们前端开发好了之后,再跟后台接口的无缝对接。
其实mock数据的方式有很多,比如写一些静态text文档,用nodejs写一个后台服务,都可以满足mock数据的需求。但是,最方便的莫过于使用mock工具库了,他可以自动的拦截ajax请求,返回配置好的mock数据。
我第一次这个库大概是2016年,感觉很方便,后来也想过它的实现原理是什么,不过当时没有想出来。最近在使用vue的ant pro时候,里面就使用了mockjs,于是准备自己写一个mockjs。
我并没有看mockjs的源码,不知道它是怎么实现的,我的想法是既然它可以拦截ajax的请求,那么肯定对原生的XMLHttpRequest做了什么处理,于是乎,我准备覆盖掉原生的XMLHttpRequest对象,这样使用ajax的时候new出来的对象是我自己写的构造函数,不就可以满足拦截ajax请求的目的了吗。
我只是实现了拦截ajax的初级功能,并没有深入,点到为止。
mockjs代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
;
// 将原生的XMLHttpRequest缓存起来
window.XMLHttpRequestMock = window.XMLHttpRequest;
// mock对象,用来存储ajax的path和返回的数据
window.mock = {
urlData: {},
setPath: function(path, data) {
this.urlData[path] = data;
}
}
// 覆盖原生XMLHttpRequest的构造函数
function XmlMock() {
this.type = null;
this.url = null;
this.onreadystatechange = null;
}
// open方法
XmlMock.prototype.open = function(type, url) {
this.type = type;
this.url = url;
this.readyState = 4;
this.status = 200
}
// send方法,这里会判断,如果请求的path在mock.urlData中则返回设置好据的数,
// 如果不在,则利用原生的XMLHttpRequest来进行ajax网络请求
XmlMock.prototype.send = function(params) {
var path = '';
var _this = this;
for(var key in mock.urlData) {
if((this.url).indexOf(key)>-1) {
path = key;
}
}
if(path) {
this.responseText = mock.urlData[path];
this.onreadystatechange(this);
}else {
var xhr = new XMLHttpRequestMock();
xhr.open('get', this.url, false);
xhr.onreadystatechange = function() {
if(xhr.readyState===4&&xhr.status===200) {
_this.responseText = xhr.responseText;
_this.onreadystatechange(_this);
}
}
xhr.send();
}
}
window.XMLHttpRequest = XmlMock;

html使用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>

</body>
<script src="./mock.js"></script>
<script>
mock.setPath('get/小明', {name: '小明'});
mock.setPath('get/小红', {name: '小红'});

fetchData('http://jinux.top/get/小明', function(res) {
console.log('小明mock数据->', res);
});
fetchData('http://jinux.top/get/小红', function(res) {
console.log('小红mock数据->', res);
});
// 测试真实的ajax数据,用的实际百度的一个链接
var testUrl = 'https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/home/js/nu_instant_search_baaa58d.js';
fetchData(testUrl, function(res) {
console.log('百度的真是数据->', res);
});
// 封装的ajax请求方法
function fetchData(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, false);
xhr.onreadystatechange = function() {
if(xhr.readyState===4&&xhr.status===200) {
callback(xhr.responseText);
}
}
xhr.send();
}
</script>
</html>

最后,附上代码,点这里