携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
Ajax
Ajax 概述
Ajax 是什么
Ajax 是 Asynchronous Javavascript XML 的缩写,被译为异步 JavaScript 和 XML 。Ajax 本身并不是一个新技术,而是一个在 2005 年被 Jesse James Garrett 提出的新术语,用来描述一种使用现有技术集合的 “新”方法。
当使用 Ajax 模型,HTML 页面能够快速地将数据逐步更新显示在用户界面上,不需要重载(刷新)整个页面。这使得 HMTL 页面能够快速的对用户的操作进行反馈。
尽管 Ajax 中的 “X” 代表 XML ,但由于 JSON 的许多优势,目前 JSON 的使用比 XML 更加普遍。 JSON 和 XML 都被用于在 Ajax 模型中封装数据。
Ajax 涉及的技术
Ajax 只是为实现异步交互的手段,不是一种技术,而是多种技术的整合。其中包括以下几种技术:
- HTML 页面
- CSS
- JavaScript 脚本语言
- Document Object Model (DOM)
- XML
- XMLHttpRequest 对象
上述技术中,XMLHttpRequest 对象是实现 Ajax 异步交互的核心。
Ajax 的核心对象
实现 Ajax 异步交互的核心就是 XMLHttpRequest 对象,该对象为客户端提供了在客户端和服务器之间传输数据的功能。
XMLHttpRequest 对象提供了一个通过 URL 来获取数据的简单方式,并且不会是整个页面刷新。这使得网页只更新一部分页面而不会打扰到用户。
XMLHttpRequest 对象最初有微软设计,随后被 Mozilla 、 Apple 和 Google 采纳。如今,该对象已经被 W3C 组织标准化。通过该对象,可以很容易地得到一个 URL 上的资源数据。尽管名字里 XML, 但 XMLHttpRequest 对象可以得到所有类型的数据资源,并不局限于 XML 格式的数据。
实现 Ajax 异步交互
实现 Ajax 的执行步骤
实现 Ajax 异步交互需要服务器逻辑进行配合,而作为客户端的 HTML 页面需要完成以下步骤:
- 创建 Ajax 的核心对象 XMLHttpRequest 对象。
- 通过 XMLHttpRequest 对象的
open()方法与服务端建立连接。 - 构建请求所需的数据内容,并通过 XMLHttpRequest 对象的
send()方法发送给服务器端 - 通过 XMLHttpRequest 对象提供的
onreadystatechange事件监听服务器端你的通信状态 - 接受并处理服务端向客户端响应的数据结果
- 将处理结果更新到 HTML 页面中
创建 XMLHttpRequest 对象。
XMLHttpRequest 对象已经被 W3C 组成进行标准化,但是还是存在 IE 浏览器的兼容问题,不过比较好的就是微软已经放弃了自家的 IE 浏览器,也就说我们几乎已经不用考虑浏览器兼容问题了。
XMLHttpRequest() 构造函数用于初始化一个 XMLHttpRequest 实例对象。在调用下列任何其他方法之前,必须先调用该构造函数,或通过其他方式,得到一个实例对象。
示例代码如下所示
var request = new XMLHttpRequest();
与服务器建立连接
通过 XMLHttpRequest 对象的 open() 方法与服务器建立连接,该方法的语法结构如下所示:
xhrReq.open(method, url, [async][, user][, password]);
参数说明:
-
method: 表示当前的请求方式常见的为 GET 和 POST
-
url: 表示当前请求的服务器端地址连接 -
async: 一个可选的布尔参数,表示是否异步执行操作,默认为true。 -
user: 可选的用户名用于认证用途;默认为null。 -
password: 可选的密码用于认证用途,默认为null。
给服务端发送数据
通过 XMLHttpRequest 对象的 send() 方法,将客户端页面的数据发送给服务端,该方法的语法结构如下所示:
xhrReq.send([body])
参数说明:
body: 在 XHR 请求中要发送的数据体,如果不传递数据则为 null
绑定 onreadystatechange 事件
onreadystatechange 事件用于监听服务器端的通信状态,该事件监听的依靠是 XMLHttpRequest.readyState 属性,该属性返回一个 XMLHttpRequest 代理当前所处的状态,只要当前属性值被改变,就触发 onreadystatechange 事件。该属性有 5 种状态,如下表所示:
| 值 | 状态 | 描述 |
|---|---|---|
0 | UNSENT | 代理被创建,但尚未调用 open() 方法。 |
1 | OPENED | open() 方法已经被调用。 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且头部和状态已经可获得。 |
3 | LOADING | 正在响应 |
4 | DONE | 响应已完毕 |
XMLHttpRequest.responseText属性用于接收服务器端的响应结果。
示例代码如下所示:
这里随便找了个 RUL 作为测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax的实现步骤</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn')
btn.addEventListener('click', function () {
// 1. 实例化 XMLHttpRequest 对象
var xhrReq = new XMLHttpRequest();
// 2. 通过 .open() 方法建立连接
xhrReq.open('GET', 'https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState');
// 3. 通过 .send() 方法向服务器端发送数据
xhrReq.send(null);
// 4. 绑定 onreadystatechange 事件
xhrReq.onreadystatechange = function () {
/* .readyState 属性表示当前状态
值 描述
0 代理被创建,但尚未调用 open() 方法。
1 open() 方法已经被调用。
2 send() 方法已经被调用,并且头部和状态已经可获得。
3 正在响应
4 响应已完毕
*/
if (xhrReq.readyState === 4) {
console.log(xhrReq.responseText);
}
}
})
</script>
</body>
</html>
执行结果如下图所示:
实现 Ajax 的异步交互的问题
onreadystatechange 事件的绑定位置
onreadystatechange 事件的绑定位置不同,XMLHttpRequest.readyState 属性的结果也不一样,上面的代码中XMLHttpRequest.readyState 属性的执行结果为
2
3
4
我们如果改一下调用位置的话,其执行结果会怎么样呢?
示例代码如下所示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实现 Ajax 异步交互</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn')
btn.addEventListener('click', function () {
var xhrReq = new XMLHttpRequest();
xhrReq.onreadystatechange = function () {
/* .readyState 属性表示当前状态
值 描述
0 代理被创建,但尚未调用 open() 方法。
1 open() 方法已经被调用。
2 send() 方法已经被调用,并且头部和状态已经可获得。
3 正在响应
4 响应已完毕
*/
console.log(xhrReq.readyState);
}
xhrReq.open('GET', 'https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState');
xhrReq.send(null);
})
</script>
</body>
</html>
执行结果如下图所示
从执行结果可以看出,Ajax 的实现步骤并不是只有那一种。
但是为什么没有状态 0 呢?这是因为我们在绑定这个之前必须完成对象的初始化,而状态 0 表示对象未初始化,所以不能得到状态 0。
根据这些状态的不同我们可以完成不同的操作。
send() 方法的问题
如果当前的请求方式为 GET 的话, send() 方法中只能传递 null 值,如果想要添加请求数据的话需要将请求添加地址连接中。
发送数据的格式如下所示
name=value
如果多个数据的话需要使用 & 分隔。
请求方式
GET 请求方式
Ajax 异步交互中使用 GET 请求方式的话,需要注意一下两个问题:
- 将构建的请求数据添加到
open()方法中的 URL 地址中。 - 发送请求数据中的
send()方法中参数设置为 null 值。
POST 请求方式
Ajax 异步交互中如果使用的是 POST 请求的话,需要注意下面两个问题
-
调用
send()方法之前,open()方法之后,需要通过XMLHttpRequest对象的setRequestHeader()方法设置请求头信息。setRequestHeader()语法结构如下所示xhrReq.setRequestHeader(header, value);参数说明:
header: 属性的名称。value: 属性的值。
-
通过 XMLHttpRequest 对象的
send()方法发送请求数据。
示例代码如下所示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST请求方式</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn')
btn.addEventListener('click', function () {
var xhrReq = new XMLHttpRequest();
xhrReq.open('POST', 'https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState');
/*
在open方法之后 send 之前设置请求头
xhrReq.setRequestHeader(header, value);
- header: 属性的名称。
- value: 属性的值。
*/
xhrReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhrReq.send('user=is_sweet&pwd=123456');
})
</script>
</body>
</html>
执行结果如下所示