网络请求 | AJAX

AJAX概述

Ajax = Asynchronous JavaScript + XML

Ajax主要依赖于XMLHttpRequest(XHR)对象,XHR为发送服务器请求和获取响应提供了合理的接口。这个接口可以实现异步从服务器获取额外数据,意味着用户点击不用页面刷新也可以获取数据。通过XHR对象获取数据后,可以使用DOM方法把数据插入网页。

AJAX优点

W3school里面是这么说的

言简意赅就是在说AJAX可以不刷新页面更新数据,AJAX可以实现与服务器的通信

1. 无刷新更新数据

这是AJAX最大的优点:不用刷新整个页面的前提下与服务器通信维护数据,有利于Web应用程序更为迅速地响应用户交互,避免了在网络上发送没有改变的信息,减少用户等待时间,带来了较好的用户体验。

2. 异步与服务器通信

AJAX使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力。优化了Browser和Server之间的沟通,减少不必要的数据传输、时间以及降低网络上的数据流量。

3. 前端和后端负载平衡

AJAX可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。AJAX的原则是”按需获取数据“,可以最大程度的减少冗余请求和响应对服务器造成的负担,提升站点性能。

4. 基于标准化被广泛支持

AJAX基于标准化的并被广泛支持的技术,不需要下载浏览器插件或者小程序,但需要客户允许在JavaScript浏览器上执行,随着AJAX的成熟,一些简化AJAX的使用方法的程序库也相继问世。

5. 界面与页面分离

AJAX是的Web中的界面与应用分离,有利于分工合作、减少非技术任意对页面的修改造成的web应用程序错误、提高效率,更加适用于现在的发布系统。

AJAX缺点

1. AJAX破坏了浏览器机制

因为AJAX是动态更新局部页面的,所以用户无法回到前一个页面状态,因为一般来说,浏览器可以通过back和history的功能回到历史记录中的静态页面,但是在AJAX中这是无法实现的。

2. AJAX的安全问题

AJAX暴露了浏览器与服务器交互的细节。

3. AJAX不能很好地兼容移动设备

一些手持设备比如手机,PAD等,现在还不能很好地支持AJAX。

AJAX工作原理

基于AJAX的介绍和工作原理,AJAX请求可以分为以下几个步骤:

  1. 新建XHR对象, let xhr = new XMLHttpRequest()
  2. 打开链接 open(),传入三个参数:请求类型,Url,请求是否异步(布尔值)
  3. 发送 send(),接收一个参数,作为请求体发出的数据,如果不需要,则必须传null
  4. 当XHR对象当完成第四步(onreadystatechange)数据接收完成,判断http响应状态(status)200-300之间或者304(缓存)执行回调函数

1. 请求类型说明

计网 | HTTP请求方法

2. 状态码说明

计网 | HTTP状态码

所以,一般来说,HTTP状态码为2xx表示成功,或者是HTTP状态码为304,表示资源未修改过,使用浏览器的缓存中拿取的,也意味着响应有效。

3. readyState说明

  • 0:未初始化(Uninitialized)。尚未调用open()方法。
  • 1:已发送(open)。已调用open()方法,但尚未调用send()方法。
  • 2:已发送(Sent)。已调用send()方法,尚未收到响应。
  • 3:接受中(Receiving)。已经收到部分响应。
  • 4:完成(Complete)。已经收到所有响应,可以使用了。

每次readyState的值发生改变的时候,都会触发readystatechange

4. xhr对象属性说明

收到响应后,xhr对象的以下属性会被填充上数据

  • responseText:作为响应体返回的文本
  • responseXML:如果响应的内容类型是text/xml 或者 application/xml,那就是包含响应数据的XML DOM文件
  • status:响应的HTTP状态
  • statusText:响应的HTTP状态描述

AJAX代码实现

1. AJAX手写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Step1: 新建XHR对象
let xhr = new XMLHttpRequest();

// Step4: 监听
xhr.onreadstatechange = function() {
if (readyState === 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
} else {
alert('Request was unsucessful!' + xhr.status);
}
}
};

// Step2: 建立连接
xhr.open('GET', url, false);

// Step3: 发送
xhr.send(null);

2. Promise封装AJAX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function myAjax(method='GET', url, isAsync=false, data=null) {
let xhr = new XMLHttpRequest();

return new Promise((resolve, reject) => {
xhr.onreadstatechange = function() {
if (readyState !== 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
resolve(xhr.responseText); // 响应体返回的文本
} else {
reject(xhr.statusText); // 响应的HTTP状态描述
};
};
xhr.open(method, url, isAsync);
xhr.send(data);
});
}

参考

https://www.w3schools.com/xml/ajax_intro.asp

https://juejin.cn/post/6844903713102888973

https://segmentfault.com/a/1190000039416782