ajax封装

ajax

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
;(function anonymous(window) {
function AJAX(options) {
return new init(options);
}

let init = function init(options = {}) {
//=>INIT PARAM
let {
url,
method = 'GET',
data = null,
dataType = 'JSON',
async = true,
cache = true,
success,
error
} = options;

//=>MOUNT:把配置项挂载到实例上
['url', 'method', 'data', 'dataType', 'async', 'cache', 'success', 'error'].forEach(item => {
this[item] = eval(item);
});

//=>SEND:发送AJAX请求
this.sendAjax();
};

AJAX.prototype = {
constructor: AJAX,
init,
//=>发送AJAX请求
sendAjax() {
this.handleData();
this.handleCache();

//=>SEND
let {method, url, async, error, success, data} = this,
xhr = new XMLHttpRequest;
xhr.open(method, url, async);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
//=>ERROR
if (!/^(2|3)\d{2}$/.test(xhr.status)) {
error && error(xhr.statusText, xhr);
return;
}
//=>SUCCESS
let result = this.handlDataType(xhr);
success && success(result, xhr);
}
};
xhr.send(data);
},
//=>处理DATA-TYPE
handlDataType(xhr) {
let dataType = this.dataType.toUpperCase(),
result = xhr.responseText;
switch (dataType) {
case 'TEXT':
break;
case 'JSON':
result = JSON.parse(result);
break;
case 'XML':
result = xhr.responseXML;
break;
}
return result;
},
//=>处理CACHE
handleCache() {
let {url, method, cache} = this;
if (/^GET$/i.test(method) && cache === false) {
//=>URL末尾追加时间辍
url += `${this.check()}_=${+(new Date())}`;
this.url = url;
}
},
//=>处理DATA
handleData() {
let {data, method} = this;
if (!data) return;
//=>如果是个OBJECT对象,我们把它转换为x-www-form-urlencoded这种模式,方便后期传递给服务器
if (typeof data === 'object') {
let str = ``;
for (let key in data) {
if (data.hasOwnProperty(key)) {
str += `${key}=${data[key]}&`;
}
}
data = str.substring(0, str.length - 1);
}

//=>根据请求方式不一样,传递给服务器的方式也不同
if (/^(GET|DELETE|HEAD|TRACE|OPTIONS)$/i.test(method)) {
this.url += `${this.check()}${data}`;
this.data = null;
return;
}
this.data = data;//=>POST系列
},
//=>检测URL中是否存在问号
check() {
return this.url.indexOf('?') > -1 ? '&' : '?';
}
};

init.prototype = AJAX.prototype;
window.ajax = AJAX;
})(window);

Pormise 形式的ajax请求

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
;(function anonymous(window) {
//=>设置默认的参数配置项
let _default = {
method: 'GET',
url: '',
baseURL: '',
headers: {},
dataType: 'JSON',
data: null,//=>POST系列请求基于请求主体传递给服务器的内容
params: null,//=>GET系列请求基于问号传参传递给服务器的内容
cache: true
};

//=>基于PROMISE设计模式管理AJAX请求
let ajaxPromise = function ajaxPromise(options) {
//=>OPTIONS中融合了:默认配置信息、用户基于DEFAULTS修改的信息、用户执行GET/POST方法时候传递的配置信息,越靠后的优先级越高
let {url, baseURL, method, data, dataType, headers, cache, params} = options;

//=>把传递的参数进一步进行处理
if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
//=>GET系列
if (params) {
url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
}
if (cache === false) {
url += `${ajaxPromise.check(url)}_=${+(new Date())}`;
}
data = null;//=>GET系列请求主体就是什么都不放
} else {
//=>POST系列
if (data) {
data = ajaxPromise.formatData(data);
}
}

//=>基于PROMISE发送AJAX
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest;
xhr.open(method, `${baseURL}${url}`);
//=>如果HEADERS存在,我们需要设置请求头
if (headers !== null && typeof headers === 'object') {
for (let attr in headers) {
if (headers.hasOwnProperty(attr)) {
let val = headers[attr];
if (/[\u4e00-\u9fa5]/.test(val)) {
//=>VAL中包含中文:我们把它进行编码
//encodeURIComponent/decodeURIComponent
val = encodeURIComponent(val);
}
xhr.setRequestHeader(attr, val);
}
}
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (/^(2|3)\d{2}$/.test(xhr.status)) {
let result = xhr.responseText;
dataType = dataType.toUpperCase();
dataType === 'JSON' ? result = JSON.parse(result) : (dataType === 'XML' ? result = xhr.responseXML : null);
resolve(result);
return;
}
reject(xhr.statusText);
}
};
xhr.send(data);
});
};

//=>把默认配置暴露出去,后期用户在使用的时候可以自己设置一些基础的默认值(发送AJAX请求的时候按照用户配置的信息进行处理)
ajaxPromise.defaults = _default;

//=>把对象转换为URLENCODED格式的字符串
ajaxPromise.formatData = function formatData(obj) {
let str = ``;
for (let attr in obj) {
if (obj.hasOwnProperty(attr)) {
str += `${attr}=${obj[attr]}&`;
}
}
return str.substring(0, str.length - 1);
};
ajaxPromise.check = function check(url) {
return url.indexOf('?') > -1 ? '&' : '?';
};

//=>GET
['get', 'delete', 'head', 'options'].forEach(item => {
ajaxPromise[item] = function anonymous(url, options = {}) {
options = {
..._default,//=>默认值或者基于defaults修改的值
...options,//=>用户调取方法传递的配置项
url: url,//=>请求的URL地址(第一个参数:默认配置项和传递的配置项中都不会出现URL,只能这样获取)
method: item.toUpperCase()//=>以后执行肯定是ajaxPromise.head执行,不会设置METHODS这个配置项,我们自己需要配置才可以
};
return ajaxPromise(options);
};
});

//=>POST
['post', 'put', 'patch'].forEach(item => {
ajaxPromise[item] = function anonymous(url, data = {}, options = {}) {
options = {
..._default,
...options,
url: url,
method: item.toUpperCase(),
data: data
};
return ajaxPromise(options);
};
});

window.ajaxPromise = ajaxPromise;
})(window);

url地址解析

1
2
3
4
5
6
7
8
9
10
//=>URL地址解析
let queryURLParams = function (url = window.location.href) {
let obj = {},
reg = /([^?=&#]+)=([^?=&#]+)/g;
url.replace(reg, (...arg) => {
let [, key, value] = arg;
obj[key] = value;
});
return obj;
};
-------------本文结束感谢您的阅读-------------