基于Promise封装属于自己的Ajax库
设置默认的参数设置项
//设置默认的参数设置项
let _default={
method:'GET',
url:'',
baseURL:'',
headers:{},
dataType:'JSON',
data:null, //POST系列请求基于请求主体传递给服务器的内容
params:null, //GET系列请求基于问号传参传递给服务器的内容
cache:true //用于清理缓存
}
因为考虑到用户在后期会使用自己设置的基础默认值,所以我们得想办法吧这个函数暴露出去
给他起个名字叫做defaults,让他继承default的所有值
ajaxPromise.defaults=_default;
接下来设置基于PROMISE设计模式管理AJAX请求
我们可以给他一个options来接收传来的所有值
注意!OPTIONS中融合了:默认配置信息、用户基于DEFAULTS修改的信息、用户执行GET/POST方法的时候传递的配置信息,越靠后的优先级越高
let ajaxPromise=function ajaxPromise(options){
let{ url,baseURL,method,data,dataType,headers,cache,params
}=options
Promise((resolve,reject)=>{
})
};
基于PROMISE发送AJAX
处理数据的代码
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(resultn,xhr);
return
}
reject(xhr.statusText,xhr)
}
如果HEADERS存在,我们需要设置请求头
循环headers依次设置
如果headers包含中文的话,我们把它进行编码
if(headers !==null && typeof headers==='object'){
//循环headers依次设置
for(let attr in headers){
if(headers.hasOwnProperty(attr)){
//如果headers包含中文的话,设置以下
let value=headers[attr];
if(/[\u4e00-\u9fa5]/.test(val)){
//val中包含中文:我们把它进行编码
//encodeURIComponent/decodeURIComponent
val=encodeURIComponent(val);
}
xhr.setRequestHeader(attr,val)
}
}
}
把传递的参数进一步进行处理
首先我们封装两个方法以便我们处理传递参数时有用
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系列
if(params){
url+=`${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`
}
if(cache===false){
url+=`${ajaxPromise.check(url)}_=${+(new Date())}`
}
data=null;//GET系列请求主体就是什么都不放
如果传递的是POST系列
//POST系列
if(data){
data=ajaxPromise.formatData(data)
}
具体代码如下
;(function anonymous(window) {
//支持设置默认的参数配置项
let _default = {
method: 'GET',
url: '',
baseURL: '',
headers: {},
dataType: 'JSON',
//POST系列请求基于请求主体传递给服务器的内容
data: null,
//GET系列请求基于问号传参传递给服务器的内容
params: null,
//设置缓存
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);
我们自己建一个用于测试我们自己封装的ajax代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<script src="js/ajaxPromise.js"></script>
<script>
//DEFAULT
ajaxPromise.defaults.baseURL = 'https://www.easy-mock.com/mock/5b0412beda8a195fb0978627/temp';
//SEND
//GET1
ajaxPromise.get('/list').then((result) => {
console.log(result);
});
//GET2
ajaxPromise.get('/info', {
params: {
id: 1000
},
cache: false
}).then((result) => {
console.log(result);
});
//POST
ajaxPromise.post('/add', {
name: 'xxx',
age: 9
}, {
headers: {
'content-type': 'x-www-form-urlencoded'
}
}).then((result) => {
console.log(result);
});
</script>
</body>
</html>