难度级别:中高级及以上 提问概率:75%
想要实现Ajax,就需要创建它的核心通信对象XMLHttpRequest,通过核心对象的open方法与服务端建立连接,核心对象的send方法可以将请求所需数据发送给服务端,服务端接收到请求并做出响应,我们通过核心对象的onreadystatechange事件监听通信状态,最终获取到响应数据,将数据与DOM元素结合,从而完成Ajax的实现过程。如果想要通过Ajax发送一个GET请求,代码如下
Javascript代码:
<script>
// 创建核心通信对象 XMLHttpRequest
let request = new XMLHttpRequest();
// 监听服务端响应
request.onreadystatechange = function(e){
if(request.readyState === 4){
if(request.status >= 200 && request.status <= 300){
// 服务端响应的数据
console.log(request.responseText);
}else {
console.log("异常信息:" + request.status);
}
}
}
// 建立与服务端通信连接
request.open('GET','http://xx.test.com');
// 发送请求
request.send();
</script>
但毕竟我们在项目开发中,情况比较复杂,请求类型包含GET和POST等,需要针对请求数组做出整合,需要针对异常响应做出及时处理等等,这些繁琐的操作都需要封装在通用的方法里。最终的目标是希望到了业务开发代码中,可以清晰的调用,可以针对业务做出数据整合即可,就像这样
Javascript代码:
<script>
ajax({
url: 'http://xx.test.com/modifyUser',
type: 'POST',
dataType: 'json',
data: {
name: '张三',
},
success: function(data){
console.log(data);
},
error: function(err){
console.log(err);
}
})
</script>
那么针对请求类型、请求数据区分和影响结果,我们可以做出简单Ajax封装,代码如下
Javascript代码:
<script>
function ajax(options) {
// 创建核心通信对象 XMLHttpRequest
let xhr = new XMLHttpRequest();
// 针对请求数据做出处理
options = options || {};
options.type = (options.type || 'GET').toUpperCase();
options.dataType = options.dataType || 'json';
let params = options.data;
// POST请求发送数据
if (options.type === 'POST') {
xhr.open('POST', options.url, true);
xhr.send(params);
} else if (options.type === 'GET') {
// GET请求发送数据
xhr.open('GET', options.url + '?' + params, true);
xhr.send(null);
}
// 接收响应数据
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
let status = xhr.status;
if (status >= 200 && status < 300) {
options.success && options.success(xhr.responseText)
} else {
options.error && options.error(status)
}
}
}
}
</script>
以上是对Ajax通用方法做出了简单的封装,但现在Ajax、Axios和Fetch都是非常流行的,那么他们有什么区别呢?
Ajax可以在不重新加载整个页面的情况下,实现对网页中某一个区域的数据更新,但随着前端开发的发展,人们逐渐发现使用Ajax会不断产生回调地狱的问题,使得代码可读性差、维护成本不断升高;Axios是基于Promise封装的网络请求库,它使用简单而且易于扩展,与Ajax和Fetch不同的是,Axios也可以用于Node服务端发起HTTP请求;Fetch是基于ES6中Promise设计实现的,需要注意的是,Fetch是为了替代Ajax出现的,所以它并没有使用XMLHttpRequest对象,它也是原生Javascript的实现。
刷题思考
很多求职者在面试的时候,有可能由于紧张忘记了XMLHttpRequest这个关键对象,其实这是很不应该的。在不要求手写Ajax的面试中,一定要熟练记住这几步:创建XMLHttpRequest核心对象、open方法用于连接、send方法用于发送、onreadystatechange用于监听响应。
类似考点
在前后端联调中使用Axios和Fetch的场景越来越多了,所以针对这一块知识点,面试官很可能还会提出以下这些问题,例如请你详细说一说Ajax、Axios和Fetch各自的优缺点是什么?例如你可以用Promise封装一个Ajax吗?例如你在Vue项目中是如何使用Axios的?