简介
ajax是Asynchronous JavaScript+XML的简写,即异步JavaScript+XML。其诞生的目的便是改善用用户的体验。
出现原因及背景
在ajax诞生之前,用户的页面上总是点击,页面会全部刷新,然后等待几分钟甚至更长的时间来重新加载资源,有时网络会超出你想象的慢,然后你的大半个小时就没了,或者在加载页面之初,你就要等待这么长的时间。这种同步的交互方式是十分头疼的,也十分影响效率和心情。为此ajax出现了,它以发送服务器额外的请求而不重新刷新页面,重新加载全部资源,而减少了网络资源加载请求,这使得请求的资源更少,加载的时间更短,用户等待白屏的时间更短,用户体验更好。为此受到了当时人们的青睐。
同步的交互方式会导致请求响应之前,阻塞后面的代码执行,而异步则不会。
具体使用
在使用ajax时候,我们可以经过如下步骤,发送http请求以及接受返回的响应。
发送请求
- 初始化XHR对象的实例。所有现代浏览器都支持XMLHttpRequest对象。在不考虑兼容问题时我们可以这么写。
//不加兼容的写法
let xhr = new XMLHttpRequest();
如果加上兼容的写法
let xhr;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xhr=new XMLHttpRequest();
}else{
// IE6, IE5 浏览器执行代码
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
在浏览器中我们可以通过使用XHR(XMLHttpRequest)对象来实现ajax请求
- 调用open方法为发送请求做准备。open方法有三个参数,即open(method,url,async)。
- method
string类型。请求方法,参数值为GET、POST、PUT、DELETE等。 - url
string类型。为资源访问地址,可以是绝对地址,也可以是相对地址。相对地址是相对于代码所在页面的。 - async
boolean类型。同步还是异步的标识,true表示该请求是异步,false表示该请求是同步
xhr.open('GET','http://www.aa.com:80/a/a',true)
url可以不写完全协议、域名、端口。此时该url会被当做相对路径处理。上面的http就是请求协议,www.aa.com是域名,冒号后面的数字就是端口号。如果不写则默认是80端口。
url有同源限制,也就是说
将要发起的资源请求和原来页面上的请求必须是域名相同、端口相同、协议相同。否则会报错。若这三者有一个不同,请求接收响应失败,这就是常说的跨域问题。
- 调用send方法,请求发送。send方法可以接受一个参数,并将该参数放置到请求的
请求体中(body)。 - send(params)。params是个string类型的字符串。如果你不需要传任何参数或者你的请求方法是
GET。那么可以写null或者不传。
//GET请求
xhr.send()
xhr.send(null)
//当POST请求时,你可以这么传,params1=1。
//即参数名=值。当需要传多个参数的时候用`&`连接,即参数名=值&参数名=值
xhr.send('params1=1¶ms2=2')
GET请求的参数直接拼接在url上就可以了。用
?隔开资源地址和参数,后面添加参数名=值。
xhr.open('GET','http://www.aa.com:80/a/a?params1=1¶ms2=2',true)
在经历过上面三个步骤后,我们的请求就已经发出了、
接收响应
当我们发送完请求后,我们需要服务端给我们一个应答,这个应答就是返回的一些我们所需的数据。那么我们该怎么接收到以及什么时候可以操作数据呢?
XMLHttpRequest对象提供了事件readystatechange。XMLHttpRequest对象有一个readyState的属性来表示当前当前的请求/响应过程处在哪一个阶段。以下是该属性的状态。
| readyState值 | 当前的阶段 | 调用的方法 |
|---|---|---|
| 0 | 未初始化 | 声明实例,还未调用open方法 |
| 1 | 已打开 | 已调用open方法 ,未调用send方法 |
| 2 | 已发送 | 已调用send方法,尚未收到响应 |
| 3 | 接受中 | 已收到部分响应 |
| 4 | 完成 | 已收到所有响应,请求响应完成 |
readyState属性是由XMLHttpRequest对象内部进行维护的,所以我们不需要去操作该属性。每当readyState的值发生改变时,就会触发readystatechange事件。因此我们只需要在监听该事件,并在接收完数据之后操作接收到的数据即可。
xhr.onreadystatechange=function(){
if(xhr.readyState == 4){
//操作数据
}
}
注意 为了保证浏览器的兼容性 xhr.onreadystatechange事件函数需要在调用
open方法之前设置
虽然上面我们知道怎么接收以及什么时候可以操作数据。但是新的问题来了,我们该从哪里获取数据呢?答案是XMLHttpRequest对象。
XMLHttpRequest对象为我们提供了四个属性:responseText,responseXML,status,statusText,当收到响应后,XMLHttpRequest对象就会在对于属性上填入对应的值。其意义如下:
- responseText: 响应体返回的文本
- responseXML:如果响应内容是XML文档,则包含在此中
- status:HTTP请求的状态码
- statusText:HTTP请求状态码的描述
我们知道之前的readyState状态只是表明我们的请求是正常的,但数据是否正常有效则是通过status来进行判断的。在http请求中,状态码在200到300之间表示从服务器得到的响应式有效的,当然还有一种情况下,响应也是有效的,那就是304,表示该资源没有修改过,我们可以从浏览器缓存中取得。所以取得响应数据代码如下。
xhr.onreadystatechange=function(){
if(xhr.readyState == 4){
//操作数据
if(xhr.status=>200&&xhr.status<300||xhr.status==304){
console.log( xhr.responseText)
}else{
//响应数据无效,可以做报错处理
}
}
}
取消请求
XMLHttpRequest对象提供了一个取消异步请求的方法,abort。实例调用后就会停止触发该实例相应的事件,并且阻止访问该实例上任何与响应相关的属性。
xhr.abort()
汇总
综合上面的讲述,ajax的使用总共分为以下步骤:
- 实例化XMLHttpRequest对象
- 设置readyState属性的监听方法onreadystatechange,以便处理响应数据
- 调用open方法,确定请求类型、目标资源地址、是否异步。如果是GET请求且需要参数,则将参数拼接在url上
- 调用send方法,发送数据。如果是post方法且需要传参,可以在这一步设置 汇总之后代码如下:
let xhr;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xhr=new XMLHttpRequest();
}else{
// IE6, IE5 浏览器执行代码
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange=function(){
if(xhr.readyState == 4){
//操作数据
if(xhr.status=>200&&xhr.status<300||xhr.status==304){
console.log( xhr.responseText)
}else{
//响应数据无效,可以做报错处理
}
xhr=undefined;//用完之后,取消对象引用
}
}
xhr.open('GET','http://www.aa.com:80/a/a?params1=1¶ms2=2',true)
xhr.send()
注意:在请响应完成后需要取消对XHR对象的引用,由于内存问题,不建议重用XHR对象实例。
最后
内容难免出错,欢迎指正交流!