AJAX
字数统计:3.7k字目录
AJAX简介
AJAX全称为“Asynchronous Javascript And XML”, 即“异步JavaScript和XML”的意思。通过AJAX我们可以向服务器发送请求,在不阻塞页面的情况下进行数据交互,也可以理解为异步数据传输。在AJAX的帮助下我们的网页只需局部刷新即可更新数据的显示,减少了不必要的数据量,大大提高了用户体验,缩短了用户等待的时间,使得web应用程序更小、更快,更友好。
优点
页面无刷新,用户体验好。
异步通信,更加快的响应能力。
减少冗余请求,减轻了服务器负担
基于标准化的并被广泛支持的技术,不需要下载插件或者小程序
缺点
ajax干掉了back按钮,即对浏览器后退机制的破坏。
存在一定的安全问题。
对搜索引擎的支持比较弱。
破坏了程序的异常机制。
无法用URL直接访问
使用场景
场景 1. 数据验证
场景 2. 按需取数据
场景 3. 自动更新页面
AJAX的核心 XMLHttpRequest对象
创建XML对象的实例:const xhr = new XMLHttpRequest()
方法
1 | # 准备启动一个AJAX请求 |
属性
1 | # 一个JavaScript函数对象,当readyState属性改变时会调用它。 |
XMLHttpRequest 方法
abort()
取消当前响应,关闭连接并且结束任何未决的网络活动。
这个方法把 XMLHttpRequest
对象重置为 readyState
为 0 的状态,并且取消所有未决的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法。
getAllResponseHeaders()
把 HTTP 响应头部作为未解析的字符串返回。
如果 readyState
小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 "\r\n"
隔开。
getResponseHeader()
返回指定的 HTTP 响应头部的值。其参数是要返回的 HTTP
响应头部的名称。可以使用任何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。
该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyState 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并返回,使用逗号和空格分隔开各个头部的值。
open()
初始化一个请求. 该方法用于JavaScript代码中;如果是本地代码, 使用 openRequest())方法代替.
注意: 在一个已经激活的request下(已经调用open()或者openRequest()方法的request)再次调用这个方法相当于调用了abort()方法。
参数:method
请求所使用的HTTP方法; 例如 “GET”, “POST”, “PUT”, “DELETE”等. 如果下个参数是非HTTP(S)的URL,则忽略该参数.url
该请求所要访问的URLasync
一个可选的布尔值参数,默认为true,意味着是否执行异步操作,如果值为false,则send()方法不会返回任何东西,直到接受到了服务器的返回数据。如果为值为true,一个对开发者透明的通知会发送到相关的事件监听者。这个值必须是true,如果multipart 属性是true,否则将会出现一个意外。user
用户名,可选参数,为授权使用;默认参数为空string.password
密码,可选参数,为授权使用;默认参数为空string.
sned()
发送 HTTP 请求,使用传递给 open() 方法的参数,以及传递给该方法的可选请求体。
setRequestHeader()
向一个打开但未发送的请求设置或添加一个 HTTP 请求(设置请求头)。
参数:header
将要被赋值的请求头名称value
给指定的请求头赋的值
发送AJAX请求
设置请求头部信息
每个HTTP请求和响应都会带有相应的头部信息,包含一些与数据,收发者网络环境与状态等相关信息。XMLHttpRequest对象提供的.setRequestHeader()方法为开发者提供了一个操作这两种头部信息的方法,并允许开发者自定义请求头的头部信息。
默认情况下,当发送AJAX请求时,会附带以下头部信息:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# 浏览器能够处理的内容类型
Accept
# 浏览器能够显示的字符集
Accept-Charset
# 浏览器能够处理的压缩编码
Accept-Encoding
# 浏览器当前设置的语言
Accept-Language
# 浏览器与服务器之间连接的类型
Connection
# 当前页面设置的任何Cookie
Cookie
# 发出请求的页面所在的域
Host
# 发出请求的页面URI
Referer
# 浏览器的用户代理字符串
User-Agent
注意:
部分浏览器不允许使用.setRequestHeader()
方法重写默认请求头信息,因此自定义请求头信息是更加安全的方法:# 自定义请求头
xhr.setRequestHeader("myHeader", "MyValue")
发送AJAX请求
1 | # 发送AJAX请求 |
处理响应
同步的GET请求响应:1
2
3
4
5
6
7
8
9
10
11const xhr = new XMLHttpRequest()
xhr.open("get", "example.php", false)
xhr.setRequestHeader("myHeader", "goodHeader")
xhr.send(null)
# 由于是同步的AJAX请求,因此只有当服务器响应后才会继续执行下面的代码
# 因此xhr.status的值一定不为默认值
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log("xhr.responseText:", xhr.responseText);
} else {
console.log("Request was unsuccessful:", xhr.status);
}
上面的代码不难理解,我们通过之前提到的xhr.status
属性(如果你忘记了,它存储着响应的HTTP状态)判断请求是否成功,如果成功的话,我们将读取xhr.responseText
属性中存储的返回值。但是,当我们的请求为异步时,问题就稍微变得复杂了,由于是异步的请求,在xhr.send(null)
语句被执行后,JavaScript
引擎会紧接着执行下面的判断语句,而这时由于尚未来得及响应,我们注定会得到一个默认的xhr.status
值,因此,我们永远都不可能获取请求的资源了。
如何解决这个问题?答案是通过为XMLHTTPRequest
实例添加onreadystatechange
事件处理程序(当然你也可以直接使用DOM2级规范规定的.addEventListener()
方法,但是注意,IE8是不支持该方法的)。
xhr实例的readystatechange
事件会监听xhr.readyState
属性的变化,你可以将这个属性想象为一个计数器,随着AJAX流程的推进而不断累加,其可取的值如下:1
2
3
4
5 0:未初始化 -- 尚未调用.open()方法
1:启动 -- 已经调用.open()方法,但尚未调用.send()方法
2:发送 -- 已经调用.send()方法,但尚未接收到响应
3:接收 -- 已经接收到部分响应数据
4:完成 -- 已经接收到全部响应数据,而且已经可以在客户端使用了
有了这个时间处理程序对AJAX进程做监听,剩下的事就简单多了,一个异步
的GET
请求代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const xhr = new XMLHttpRequest()
# 等价于 xhr.onreadystatechange = function(){}
# 利用onreadystatechange监测状态
xhr.onreadystatechange = () => {
# readyState为4表示请求响应完成
if(xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log("xhr.responseText:", xhr.responseText);
} else {
console.log("Request was unsuccessful:", xhr.status);
}
}
}
xhr.open('GET', 'example.php', true)
xhr.send(null)
其他库框架中的AJAX
jQuery中的AJAX
1 | $.ajax({ |
Vue.js中的AJAX
1 | Vue.http.get('/test/').then((response) => { |
状态值和状态码
状态值于状态码:
在ajax时间运行过程中,对于访问XMLHttpRequest不是一次就完成的,而是经历多种状态后获取的结果。
对于这种状态在ajax中分为5中状态:
0: (未初始化)还没有调用send()方法。
1: (载入)已经调用send()方法,正在派发请求。
2: (载入完成)send()已经执行完成,已经接收到全部的响应内容。
3: (交互)正在解析响应内容。
4: (完成)响应内容已经解析完成,用户可以调用。
ajax状态值和状态码的区别:
ajax的状态值指,运行ajax时运行的几种状态,无论是成功还是失败都要响应的步骤。如:正在派发,正在响应等,由ajax对象和
服务器之间交互是所得。使用ajax.readyState获得(0~4)
ajax状态码是值,ajax无论请求是否成功,根据http所提及的用户信息,用服务器返回http头信息代码,使用ajax.state来获得
这就是我们在使用AJAX时为什么采用下面的方式判断所获得的信息是否正确的原因。
if(ajax.readyState == 4 && ajax.status == 200) {
putData(ajax.responseText);
}
ajax状态码:
1 | AJAX状态码说明 |
ajax类库
1 | <script type="text/javascript"> |
转载:
使用AJAX