自己练习封装的基于promise的ajax
// ajaxPromise.js
~ function (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);
}
}
//=> 把对象转换为urlencoded格式的字符串
ajaxPromise.formatData = function (obj) {
let str = ``;
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
str += `${key}=${obj[key]}&`;
}
}
return str.substring(0, str.length - 1);
};
//=> 检测url是否有?传参
ajaxPromise.check = function (str) {
return str.includes('?') === true ? '&' : '?';
}
//=> 基于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中包含中文:我们把它进行编码
// encodeURLComponent / decodeURLComponent
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类型
switch (dataType) {
case 'JSON':
result = JSON.parse(result);
break;
case 'XML':
result = xhr.responseXML;
break;
}
resolve(result);
window.ajaxPromise.nowXHR = xhr;
return;
}
reject(xhr.statusText);
window.ajaxPromise.nowXHR = xhr;
}
}
xhr.send(data);
})
};
//=> defaults暴露出去,以后别人可以修改
//=> 把默认配置暴露出去,后期用户在使用的时候可以自己设置一些基础的默认值(发送ajax请求的时候按照配置的信息进行处理)
ajaxPromise.defaults = _default;
//=> get
['get', 'delete', 'head', 'options'].forEach(item => {
ajaxPromise[item] = function (url, options = {}) {
options = {
..._default, //=> 默认值或者基于defaults修改的值
...options, //=> 用户调取方法传递的配置项
url: url, //=> 请求的url地址 (第一个参数:默认配置项和传递的配置项中都捕获出现url,只能这样做)
method: item.toLowerCase() //=> 以后执行肯定是ajaxPromise.head执行,不会设置methods这个配置项,我们自己需要配置才可以
};
return ajaxPromise(options);
}
});
//=> post
['post', 'put', 'patch'].forEach(item => {
ajaxPromise[item] = function (url, data = {}, options = {}) {
options = {
..._default,
...options,
url: url,
method: item.toLowerCase(),
data: data
};
return ajaxPromise(options);
}
})
//=> 暴露出去
window.ajaxPromise = ajaxPromise;
}(window)
用法
<script src="ajaxPromise.js"></script>
<script>
//=> 默认设置
//=> 设置默认请求路径
ajaxPromise.defaults.baseURL = 'https://www.easy-mock.com/mock/5b0412beda8a195fb0978627/temp';
ajaxPromise.get('/list').then(result=>{
console.log(result);
})
ajaxPromise.get('/info',{
params: {
id:1000
},
cache:false
}).then(result=>{
console.log(result);
})
ajaxPromise.post('/add',{
name:'jun',
age:16
},{
headers:{
'content-type':'x-www-form-urlencoded'
}
}).then(result =>{
console.log(result);
})
</script>