什么是Ajax
-
Ajax全程为 Asynchronous JavaScript and XML,只有这些英文首字母缩写而成,意思就是异步的JavaScript和XML。
-
Ajax就是JavaScript基于XMLHttpRequest对象与服务端进行交互,向服务端发送一个请求,并且获取和处理服务端返回的内容。在这个过程中,我们可以使用XML、HTML和JSON等格式的数据进行交互。并且,Ajax是异步的,我们可以在不刷新页面的情况下,通过交互数据,在页面上做到局部的刷新等数据处理。
-
Ajax 能够提供一种异步请求数据,局部刷新页面的办法。
-
XMLHttpRequest 是 Ajax 的核心技术,我们通过它来向服务器发起异步请求,从服务器获得数据。
Ajax的工作原理
-
JavaScript通过XMLHttpRequest向后端发起异步请求,可以是get或者post等
-
服务端接收请求,处理并返回数据
-
JavaScript通过XMLHttpRequest获取并解析服务端返回的数据内容
-
JavaScript通过动态更新DOM或者执行其他操作
Ajax的优点
Ajax技术的优势有如下几点:
-
无需刷新页面即可更新页面
-
减少客户端的内存消耗
-
将部分传统技术中原本在服务端的工作转移到客户端来进行
-
兼容性好,几乎所有的浏览器都支持
Ajax的缺点
-
破坏浏览器的后退与加入收藏书签功能
-
网络延迟造成用户体验差
-
Ajax造成的竞态关系
什么是XMLHttpRequest
XMLHttpRequest实质上就是一种具有发送异步请求功能的技术,是一个可以在JavaScript,JScript,VBScript等脚本语言中使用的API对象。它可以通过异步发送HTTP请求,完成前后端的交互。在我们的客户端界面上,无刷新交互只是一种表现,而异步发送请求才是这个技术的根本
XMLHttpRequest的属性和方法
属性
- 标准属性
属性名 | 备注 |
---|---|
onreadystatechange | 当 readyState 发生变化时候触发 |
readyState | 请求状态码。 |
response | 返回一个 Blob 、ArrayBuffer 、Document 或 DOMString。类型受 responseType 影响。 |
responseText | 返回一个 DOMString。请求不成功或者未发送情况下返回 null。 |
responseType | 响应类型。 |
responseURL | 返回序列化 URL,URL 为空则返回空字符串。 |
responseXML | 返回一个 Document。请求未发送、不成功或者解析失败,返回 null。 |
status | 请求的响应状态。 |
statusText | 返回一个 DomString, 包含 http 响应状态。 |
timeout | 超时。定义一个最大的请求响应时间。 |
ontimeout | 超时调用事件。 |
upload | 上传过程。 |
withCredentials | 指定跨域请求是否带有授权信息。 |
- 非标准属性
属性名 | 备注 |
---|---|
channel | 一个 nsIChannel,当执行请求时,对象使用的通道。 |
mozAnon | 布尔值。为 true 情况下,请求在将在没有身份验证 header 头和 cookie 的情况下发送。 |
mozSystem | 布尔值。为 true 情况下,请求将不强制执行同源策略。 |
mozBackgroundRequest | 布尔值。指示是否是服务器的请求。 |
方法
- 标准方法
方法名 | 备注 |
---|---|
abort | 中止请求 |
getAllResponseHeaders | 返回所有用 CRLF 分隔的响应头的字符串的形式。没有收到响应则返回 null。 |
getResponseHeader | 返回指定响应头的字符串。未收到响应,或者响应不存在该报头,返回 null。 |
open | 初始化一个请求。 |
overrideMimeType | 重写 MIME 类型。 |
send | 发送请求。 |
setRequestHeader | 设置 HTTP 请求头。 |
- 非标准方法
方法名 | 备注 |
---|---|
openRequest | 初始化一个请求。 |
事件
事件名 | 备注 |
---|---|
abort | 停止请求的时候触发。 |
error | 当请求发生错误的时候触发。 |
load | 请求成功完成的时候触发。 |
loadend | 请求结束的时候触发。 |
loadstart | 收到响应数据的时候触发。 |
progress | 接收数据开始周期时候触发。 |
timeout | 超时未接收到数据的时候触发。 |
XMLHttpRequest.readyState
在客户端与服务器的通信过程中,XMLHttpRequest.readyState 体现着当前请求以及服务端响应的状态
readyState的状态码有0、1、2、3、4,它们分别代表着:
-
0:状态为 UNSENT。表示请求未初始化。
-
1:状态为 OPENED。表示服务器连接已建立。
-
2:状态为 HEADERS_RECEIVED。表示请求已接收。
-
3:状态为 LOADING。表示请求处理中。
-
4:状态为 DONE。表示请求已完成,且响应已就绪。
注意: onreadystatechange 事件被触发 4 次(0 - 4), 分别是: 0-1、1-2、2-3、3-4,对应着 readyState 的每个变化。
XMLHttpRequest.status
服务器响应完成之后,我们通常会使用 XMLHttpRequest.status 来查看当前 XMLHttpRequest 响应中的数字状态码。这个数字状态码是一个无符号短整型状态码,代表着我们的 Ajax 请求的状态成功与否。
在 XMLHttpRequest 中, status 码对应着标准的 HTTP 状态码。并且在请求完成前,该值为 0。
HTTP 响应状态代码指示特定 HTTP 请求是否已成功完成。响应分为五类:
- 信息响应(
100
–199
), - 成功响应(
200
–299
), - 重定向(
300
–399
), - 客户端错误(
400
–499
) - 服务器错误 (
500
–599
)。
具体可以到 HTTP 响应代码 进行学习和查阅
示例代码
function sendAjax(url) {
let xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
}
sendAjax("https://api.apiopen.top/getJoke");
fetch
fetch是基于promise进行设计的,写法上也更加的方便和简单,更为符合关注点分离的原则,不会讲所有的配置和状态混淆在一个对象里。
示例代码:
// 写法一
fetch("https://api.apiopen.top/getJoke")
.then((response) => {
if (response.ok) {
return response.json();
}
})
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
// 写法二
const fetchSend = async (url) => {
try {
const response = await fetch(url);
if (response.ok) {
const data = await response.json();
console.log(data);
}
} catch (error) {}
};
fetchSend("https://api.apiopen.top/getJoke");
优点:
-
代码组织简单干净,更具语义性
-
可以结合async/await书写,体验更佳
缺点:
-
原生支持率不高,兼容性差
-
只对网络请求报错,对于诸如400和500之类的错误,并不会走reject分支
-
不支持abort和超时控制
-
无法检测请求进度
axios
axios 在浏览器端实际上也是基于 XMLHttpRequest 来实现的,并且基于 promise 提供了一套 promise 风格的链式调用 API
示例代码
axios.get('https://api.apiopen.top/getJoke', {
params: {
page: 1,
count: 20,
type: 1
}
}).then(res => {
console.log(res.data.result);
}).catch(err => {
console.log(err);
})
优点
-
支持promise API
-
支持请求和响应拦截
-
提供并发请求接口功能
-
轻量高效、简单易用
-
客户端支持防止CSRF
-
支持node端