自己封装的,可以直接使用:
const ajax = options => new Promise((resolve,reject)=>{
//里面的内容是我们封装好的Ajax
//那么我们再获取元素成功后就可以使用resolve
//1.确保传入的是一个对象
let isObject = Object.prototype
.toString.call(options)
.replace(/[\[\]]/g, "")
.substr(7)
.toLowerCase()
if (isObject !== 'object') {
//传入的不是一个对象,抛出异常
throw new Error('传入的必须是一个对象, the param expected a object,but got a ' + isObject)
//下面的代码不会执行
}
//默认对象,需要和传入的options进行混合,mix
let obj = {
url: "fsdfsdf",
success: function () {
}
}
let defaultOption = {
url: "",//请求地址
method: "get",//请求方式,默认为get
responseType: "json",//返回JSON或者纯文本取值范围 json/text
data: {},//需要传递的参数
async: true,//默认是异步的
headers: { //请求头默认为from形式
"Content-Type": "application/x-www-form-urlencoded"
},
success: function (res) {//请求成功回调的函数
},
error: function (e) { //请求失败回调的函数
}
}
//让此对象,和传入的对象混合,考虑到将来用户传入的参数不全,那么没传的参数采用默认值
//传了的参数,值就=传入的参数
for (var k in options) { //遍历这个对象,因为传入的是一个对象,所以使用for in 。
//两个对象混入的方法(mix)
if (k === 'method') {//如果用户传入的数据中有method这个方法
defaultOption[k] = options[k].toLowerCase()//此代码的意思是将用户传入的 数据赋给默认值 。toLowerCase()表示的是,如果用户传入的参数是大写,则将其转换为小写
} else {
defaultOption[k] = options[k];//表示入如果传入的值中没有method,则也让其他的值赋给这个默认的值,以替换默认的值
}
}
//解构赋值
let { url, method, async, data, headers, success, responseType, error } = defaultOption;//解构是指将对象或数组的某个或多个元素的值,从其中取出来。此处指的是,将属性从defaultOption中取出来
//2.创建ajax对象
let xhr;
if (window.XMLHttpRequest) {
//现代浏览器
xhr = new XMLHttpRequest()
} else {
//兼容IE浏览器
xhr = new ActiveXObject('microsoft.XMLHTTP')
}
//3.处理传入参数data
let params = ""; //用于用户存储处理好的参数
/* 处理用户传入的参数:
把 data: {key: "all",city: "上海"}处理成 key=all&city=上海
首先处理的data不能是一个{} */
if (JSON.stringify(data) !== "{}") {//表示如果字符串类型的data不是一个空数组
//不是个空对象
for (k in data) {
params += k + "=" + data[k] + "&" //此时如果打印params则会打印为:'key=all&city=上海&'
}
params = params.substr(0, params.length - 1) //为了去掉最后面的&符号,substr(start index,final index)表示截取字符串,第一个值表示,开始的索引值,第二个值表示结束的索引
}
//4.发送请求
//这里需要携带参数
//get请求的参数是拼接在地址后面的 ?name=李磊
//传递参数需要先判断是不是get请求,并且有没有传递参数,还要考虑用户传递是不是一个大写的get,统一转成小写
//代码的含义
//因为params是通过data处理得来的,所以要保证用户传递了data并且是get请求
//需要使用?+params参数 => ?key=all&city=上海
//url的结果是http://chst.vip/weather/getWeather
//最终拼接的结果http://chst.vip/weather/getWeather?key=all&city=上海
// console.log(url + (!!params && method === 'get' ? "?" + params : ""));
xhr.open(method, url + (!!params && method === 'get' ? "?" + params : ""), async)
//post要放在send里面
//application/json => 传递json
//x-www-form-urlencoded =>传字符串 name=李磊&age=30
//处理post请求的参数
//根据请求头处理
// console.log(headers);
if (typeof headers === 'object') {//如果header是一个对象
if (JSON.stringify(headers) === "{}") { //如果header是一个对象并且如果header是一个空对象,则传递一个error,
error("请求头传递的是一个空对象", xhr)
}
} else {
throw new Error("headers expected object but got a " + typeof headers);//表示如果是不是一个对象则会丢出一个错误
reject("headers expected object but got a " + typeof headers)
}
for (var h in headers) { //headers在上面解构了,遍历这个headers。
//判断content-type这个请求头
//必须保证是post请求,并且data不是一个空对象
if (h.toLowerCase() === "content-type" && method === "post" && JSON.stringify(data) !== "{}") {
// console.log(h);
//再判断值是不是application/json
if (headers[h].toLowerCase() === "application/json") {
//将传入的data转换成json格式
params = JSON.stringify(data)
}
}
//设置请求头
xhr.setRequestHeader(h, headers[h])
}
// console.log(params);
xhr.send(method !== "post" ? null : params)//一个三元表达式,如果method不是post请求则,为null,如果是post请求则为处理好的params
//5响应
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
//成功
let res = xhr.responseText;//获取响应的结果
switch (responseType.toLowerCase()) {
case "text": //返回纯文本
success(res);
resolve(res)
break
case 'json'://返回json
success(JSON.parse(res))
resolve(JSON.parse(res))
break;
default:
success(res);
resolve(res)
}
}
}
}
xhr.onerror = function (e) {
//处理错误
error(e, xhr)
//失败的回调
reject(e,xhr)
}
})
调用ajax的方式:
ajax({//在这里我们只传递了一个url
url: 'http://chst.vip:8081/data/index.json' //调用的地址
method:'get', //请求数据的方法
data: { //需要传递的参数
shopid :shopid,
areaid :areaid,
},
async: true,//默认是异步的
headers: { //请求头
"Content-Type": "application/x-www-form-urlencoded"
},
})
//如果可以返回数据则我们可以使用then
.then(res => { //请求数据成功,执行下面的代码
console.log(res);//打印的结果是上面的url返回的数据
return ajax({
url: 'http://chst.vip/weather/getWeather'//在第一个then中返回一个ajax,则在第二个then中就可以调用
})
})
.then((res) => {
console.log(res);//打印的结果是第一个then返回的url的数据
})
.catch((err) => {//当不能传入数据的时候,才会调用这个catch回调函数
console.log('出错了');
console.log(err);
})