封装的套路:
- 写一个相对比较完善的用例
- 写一个空函数,没有形参,将刚刚的用例直接作为函数的函数体
- 根据使用过程中的需求抽象参数
// 创建XHR核心对象
let createXHR = () => {
if (window.XMLHttpRequest) {
// 现代浏览器兼容
return new XMLHttpRequest();
}
// IE兼容
return new ActiveXObject('Microsoft.XMLHttp');
}
// 传递参数拼接 封装
let getparams = json => {
let str = '';
for (let k of Object.keys(json)) {
str += k + '=' + json[k] + '&';
}
str = str.slice(0, str.length - 1);
return str;
}
// 封装ajax
let ajax = opts => {
opts.type = opts.type == undefined ? 'get' : opts.type; //默认get方式
opts.async = opts.async == undefined ? 'true' : opts.async; //默认异步
opts.dataType = opts.dataType == undefined ? 'json' : opts.dataType; // 默认使用json格式
opts.data = opts.data == undefined ? {} : opts.data;
let xhr = createXHR();
// 判断请求方式 get/post
if (opts.type == 'get') {
xhr.open('get', opts.url + '?' + getparams(opts.data), opts.async);
xhr.send(null);
} else {
xhr.open('post', opts.url, opts.async);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(getparams(opts.data));
}
// 判断同步/异步方式
if (opts.async) {
// 监听请求状态(当 readyState 改变时,就会触发 onreadystatechange 事件)
xhr.onreadystatechange = function () {
/*
xhr.readyState:
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
*/
if (xhr.readyState == 4) {
// 请求处理到了最后一步
getResult()
}
}
} else {
// 请求处理到了最后一步
getResult();
}
// 处理回调数据
let getResult = () => {
/*
xhr.status 状态码
100+ 请求已被接受,需要继续处理
200+ 请求已成功被接受和处理
300+ 通常代表重定向
400+ 客户端请求发生了错误
500+ 服务端发生了错误
*/
if (xhr.status >= 200 && xhr.status < 300) {
let res;
// 若回调参数为 json 类型,则将其进行JSON.parse转换
if (opts.dataType == "json") {
res = JSON.parse(xhr.responseText); //返回json数据
} else {
res = xhr.responseText; //返回纯text
}
opts.success(res);
} else {
opts.error();
}
}
}
// 调用方法 :
// ajax({
// url:'xxx' // 必须
// data: { }, // 参数 默认为空 非必须
// type: "post", // 请求方式 默认get 非必须
// async: true, // 同步/异步 默认异步 非必须
// dataType: 'json', // 回调参数类型 默认json 非必须
// success(cbVal) { // 成功后的回调函数 非必须
// console.log(cbVal);
// },
// error() { // 状态不为200时的回调函数 非必须
// console.info('请求失败');
// }
// })