这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战
在日常项目中,相信大家经常使用axios来请求数据,它本身就是基于XMLHttpRequest对象来实现的请求库,jquery同样也封装了一个ajax函数,来实现我们的数据请求操作,今天我们来带着大家来实现ajax。什么是Ajax呢?简单的说就是,在不重新加载网页的情况下,AJAX 通过后台加载数据,并在网页上进行显示。
XMLHttpRequest
XHR对象用于与服务器交互,通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。
如何实现一个简单的请求呢,我们先以一个get请求为例,在使用XMLHttpRequest时,我们需要初始化一个实例对象xhr,即
var xhr = new XMLHttpRequest();
在初始化一个对象后,我们需要告诉Ajax对象要向哪发送请求,以什么方式发送请求,即
// 1)请求方式 2)请求地址
xhr.open('get', 'http://localhost:3000/first');
接着我们需要发送我们的请求如下,值得我们需要注意的是,当他是post方法时,我们应该改成 xhr.send(params);,get请求是拼接在url上的。
xhr.send();
最后,我们需要监听我们请求状态的改变,是否完成,成功还是失败
// 获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
除了onload事件外,我们还可以监听onloadend事件,或者onreadystatechange事件,根据request.readyState判断请求状态,具体可以查看MDN: readyState
至此,我们简单的一个get请求就发送成功了,也对 XMLHttpRequest对象有了一点了解。
如何封装一个ajax
讲完 XMLHttpRequest对象,我们就来看看怎么实现一个ajax函数吧,让他能支持我们发送请求,我们就默认大家都使用过了,就不介绍怎么使用了。
我们先来分析一下怎么传参,get和post的请求参数是不同的,还有请求参数格式的问题,比如application/x-www-form-urlencoded和application/json,这些都是我们需要考虑的;在一个,我们不需要每次都传一些参数,比如method为get时,我们可以不传,默认就是。可以具体来看我们的代码实现。
function ajax(options) {
// 存储的是默认值
var defaults = {
type: 'get',
url: '',
data: {},
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function () { },
error: function () { }
};
// 使用options对象中的属性覆盖defaults对象中的属性
Object.assign(defaults, options);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 拼接请求参数的变量
var params = '';
// 循环用户传递进来的对象格式参数
for (var attr in defaults.data) {
// 将参数转换为字符串格式
params += attr + '=' + defaults.data[attr] + '&';
}
// 将参数最后面的&截取掉
// 将截取的结果重新赋值给params变量
params = params.substr(0, params.length - 1);
// 判断请求方式
if (defaults.type == 'get') {
defaults.url = defaults.url + '?' + params;
}
/*
{
name: 'zhangsan',
age: 20
}
name=zhangsan&age=20
*/
// 配置ajax对象
xhr.open(defaults.type, defaults.url);
// 如果请求方式为post
if (defaults.type == 'post') {
// 用户希望的向服务器端传递的请求参数的类型
var contentType = defaults.header['Content-Type']
// 设置请求参数格式的类型
xhr.setRequestHeader('Content-Type', contentType);
// 判断用户希望的请求参数格式的类型
// 如果类型为json
if (contentType == 'application/json') {
// 向服务器端传递json数据格式的参数
xhr.send(JSON.stringify(defaults.data))
} else {
// 向服务器端传递普通类型的请求参数
xhr.send(params);
}
} else {
// 发送请求
xhr.send();
}
// 监听xhr对象下面的onload事件
// 当xhr对象接收完响应数据后触发
xhr.onload = function () {
// xhr.getResponseHeader()
// 获取响应头中的数据
var contentType = xhr.getResponseHeader('Content-Type');
// 服务器端返回的数据
var responseText = xhr.responseText;
// 如果响应类型中包含applicaition/json
if (contentType.includes('application/json')) {
// 将json字符串转换为json对象
responseText = JSON.parse(responseText)
}
// 当http状态码等于200的时候
if (xhr.status == 200) {
// 请求成功 调用处理成功情况的函数
defaults.success(responseText, xhr);
} else {
// 请求失败 调用处理失败情况的函数
defaults.error(responseText, xhr);
}
}
}
ajax({
type: 'post',
// 请求地址
url: 'http://localhost:3000/responseData',
success: function (data) {
console.log('这里是success函数');
console.log(data)
}
})