(function () {
function ajax(options) {
//new ajax() //死递归
return new init(options);
}
ajax.prototype = {
constructor: ajax,
send: function () {
//this-->当前的实例
let {
method,
url,
async,
data,
timeout,
headers,
success,
cache,
error,
dataType
} = this.options
//专门用来发送请求
//把当前的xhr放到init(ajax)的实例上,方便以后查看
let xhr = this.xhr = new XMLHttpRequest;
//1.首先看一下当前的data是对象还是字符串,如果是字符串那就不用处理,如果是对象,那就把它转换成字符串
//'name=1&age=2'
//{name:1,age:2}-->'name=1&age=2'
data = this.handleData();
//2.查看一下当前是否是get系列请求,如果是的话那就看看data有没有值,如果data有值那就直接拼接到url的后面
let reg = /^(GET|DELETE|HEAD|OPTIONS)$/i;
if (data && reg.test(method)) {
//http://www.baidu.com
//http://www.baidu.com?sex=0
url += `${this.hasQuestionMark(url)}${data}`;
// this.options.url=url;
data = null; //如果是get请求,在把data使用完成之后就把他赋值为null,这样就不会在send里传递了
}
//3.如果是get系列请求,并且cache的值是false,说明不走缓存(在url后面拼接一个时间戳或者随机数)
if (reg.test(method) && !cache) {
let num = Math.random();
url += `${this.hasQuestionMark(url)}_=${num}`;
// this.options.url=url;
}
//4.处理请求超时的时间设置
if (timeout) {
xhr.timeout = timeout;
}
xhr.open(method, url, async);
//5.设置请求头(必须在open之后,send之前) headers是一个对象
if (headers) {
for (let key in headers) {
if (!headers.hasOwnProperty(key)) {
break;
}
xhr.setRequestHeader(key, encodeURI(headers[key]))
}
}
xhr.onreadystatechange = function () {
//在这里做响应的处理
let {
readyState,
responseText,
responseXML,
status,
statusText,
response
} = xhr;
if (readyState == 4) {
let res = '';
if (/^(2|3)\d{2}$/.test(status)) {
//成功的处理
switch (dataType.toUpperCase()) {
case 'JSON':
res = JSON.parse(response);
break;
case 'TEXT':
res = responseText;
break;
case 'XML':
res = responseXML;
break;
}
success && success(res, statusText, xhr);
} else {
//错误的处理
error && error(null, statusText, xhr)
}
}
}
xhr.send(data);
},
//封装一个方法,专门用来处理对象转字符串的
handleData: function () {
//对data参数进行处理,规定当前函数的返回值就是处理完成之后的字符串
let {
data
} = this.options;
//let data=this.options.data;
//如果当前的data是null或者是字符串,那就直接返回即可
if (data === null || typeof data === 'string') {
return data;
}
//只要上面的if没有成立,那就说明当前的data就是对象
let str = ``;
for (let key in data) {
//为了防止把原型上的可枚举的属性遍历出来,利用hasOwnProperty处理一下
if (!data.hasOwnProperty(key)) {
break;
}
str += `${key}=${data[key]}&`;
}
return str.slice(0, str.length - 1); //把最后的&截取下去
},
//根据url情况考虑拼接data时前面应该添加?还是&
hasQuestionMark: function (url) {
//此函数会直接返回?或者&
//this-->实例
if (!url) {
url = this.options.url;
}
return url.includes('?') ? '&' : '?';
},
}
//默认的参数配置
let defaults = {
url: '',
method: 'GET', //默认是get请求,不区分大小写
data: null,
dataType: 'JSON',
async: true,
cache: true,
timeout: null,
headers: null, //{}//请求头中的值不能是汉字
success: null, //请求成功之后的回调
error: null,
}
function init(options) {
//形参options就是用户传递的实参 this-->实例
//1.把用户传递的options和默认的defaults进行合并,以用户传递的参数为主,如果用户没有传递某个参数,那就使用默认的
// this.options=Object.assign(defaults,options)
this.options = {
...defaults,
...options
}; //把两个对象进行合并,如果出现相同的属性名,后边会覆盖前边的
if (!this.options.url) {
throw new Error('url is must be provided')
}
//2.发送ajax请求
this.send();
}
init.prototype = ajax.prototype; //把ajax的原型赋值给init的原型
if(typeof window !== "undefined"){
window.ajax = ajax; //把ajax方法暴露在window上
}
})()
let res = ajax({
url: './xxx.json',
method: 'get',
data: {
name: 1,
age: 2
},
cache: false,
headers: {
ss: 100,
aa: '中国'
},
success: (data, statusText, xhr) => {
console.log(data, statusText, xhr);
},
error: (data, statusText, xhr) => {
console.log(data, statusText, xhr);
}
}) //init的实例
console.log(res.xhr);
ajax简单封装
最新推荐文章于 2024-04-02 11:07:22 发布
本文详细介绍了如何使用JavaScript的AJAX实现HTTP请求,包括数据对象转字符串、GET请求参数处理、超时设置、请求头管理,以及成功和错误回调的处理。通过实例展示了如何配置AJAX请求并控制缓存和异步行为。
摘要由CSDN通过智能技术生成