ajax在我们的开发中是必须使用的一个技术,ajax即异步的javascript和xml但是现在我们通常使用json来完成数据的交互,ajax职责很单一就是数据的交互,发送数据接收数据是它的核心功能也是唯一的功能。
ajax的实现依赖xmlhttprequest,它的基本使用如下:
var xhr;
window.xmlhttprequest?xhr = new xmlhttprequest():xhr = new activexobject("microsoft.xmlhttp");
xhr.open("get","demo!register.action?name=zt&age=23",true);
xhr.send(null);
xhr.onreadystatechange = function(){
if(xhr.readystate==4&&xhr.status==200){
alert(json.parse(xhr.responsetext));
}
}
ajax的职责就是发送数据和接收数据我们基本使用流程为:
1.获取一个xmlhttprequest对象
2.发送数据
3.接收处理服务器返回的数据
根据上面的步骤来实现一个异步请求数据的过程,首先获取一个xhr对象,在现代浏览器中我们可以直接通过实例化来获取一个xhr对象:var xhr = new xmlhttprequest();在ie5、ie6中我们必须使用activexobject来获取xhr对象:var xhr = new activexobject("microsoft.xmlhttp")。
此时我们已经得到了xhr对象接下来就是发送数据,通过xhr.open()方法来执行发送数据的方式,xhr.open()可以接收5个参数,我们经常使用的是前三个:
xhr.open(arg1,arg2,arg3)
arg1表示请求数据的方式一般为get或者post
arg2表示请求的服务器地址
arg3表示本次请求是同步还是异步,ajax的突出特点就是异步所以我们一般都是使用异步的方式第三个参数设置为true(true表示进行异步请求false表示进行同步请求)
xhr.open()方法只是准备一个请求,在调用open之后并不会和服务器进行通讯,而是在调用send()函数之后才会和服务器开始通讯,send()函数的参数将作为请求体发送到服务端。如果我们在open()函数中指定请求的方式为get通常我们将send()设置为xhr.send(null),如果我们希望通过请求体发送数据则要将open()函数的请求方式设置为post同时将我们需要发送的数据作为send()函数的参数:xhr.send(param),在调用send()函数之后,和服务器的通讯就开始了。
对xhr的所有的设置都应该在send()函数之前设置好:
xhr.open(...);
xhr.setrequestheader(...);
xhr.overridemimetype(...);
xhr.onreadystatechange = function(){...};
xhr.send(...);
但是由于xhr.onreadystatechange是一个事件,所以其放在send()之后也是可以执行的,出于易读性我们一般都将对xhr的设置放在send()函数之前。
在send()之后可以通过xhr.readystate和xhr.status的来监测本次请求的状态,如果满足xhr.readystate==4&&xhr.status==200则本次请求成功:
在请求成功时我们可以通过xhr.responsetext来获取服务器返回的数据,需要注意xhr.responsetext是一个字符串。
ajax常用api
上面的请求过程是一个最基本的请求过程xhr对象还有几个经常使用的方法分别为xhr.abort()、xhr.setrequestheader()、xhr.overridemimetype()。
xhr.abort():终止一个请求,直接调用即可不需要设置参数
xhr.abort()
xhr.setrequestheader():设置发送的请求头:
xhr.setrequestheader("content-type","application/json; charset=utf-8")
第一个参数表示要设置的header,第二个参数表示要设置的header的值。xhr.setrequestheader()必须在xhr.open()和xhr.send()之间,否则会抛出异常,同时xhr.setrequestheader()的第一个参数是对大小写不敏感的只要我们字母写的对就能够设置成功,但是出于易读性我们要设置为正确的格式。
xhr.overridemimetype():重写响应头的content-type:
xhr.overridemimetype('text/plain; charset=utf-8')
xhr.overridemimetype()同样要设置在xhr.send()之前。
json.parse()和json.stringify()使用
json.parse()用来将一个对象转换为字符串,json.stringify()用来将一个字符串转换为对象。在利用ajax进行数据交互的过程中返回的数据多数的时候是一个json格式的字符串,如果服务器给我们返回了数据此时我们就需要利用json.parse()来解析返回的数据(xhr.responsetext即为服务器返回的数据):
xhr.onreadystatechange = function(){
if(xhr.readystate==4&&xhr.status==200){
var data = json.parse(xhr.responsetext);
}
}
在使用post方式发送数据的过程中,如果不是文件上传一般情况下传输的也是一个json数据,要想能够成功的发送到后台就需要用json.stringify()来将json对象来转换为一个字符串,同时content-type要设置为application/json:
var senddata = {name:"zt",age:23};
...
xhr.setrequestheader("content-type","application/json; charset=utf-8");
xhr.send(json.stringify(senddata));
另外利用json.parse()和json.stringify()可以实现一个对象的深拷贝功能:
var senddata = {name:"zt",age:23};
var copydata = json.parse(json.stringify(senddata));
$.ajax基本使用
为了方便使用jq为我们封装好了一个ajax来方便我们的使用:
$.ajax({
type:"post",//请求方式
url:"url",//请求地址
data:"...",//发送至服务端的数据
contenttype:"...",//设置发送数据的类型如果data是一个json字符串这里要设置为application/json
success:function(data){...},//请求成功的回调函数data可看做是服务器返回的数据
error:function(){...}//请求失败的回调函数
});
或者:
$.ajax({
type:"post",
url:"url",
data:"...",
contenttype:"...",
})
.done(function(data){...})
.fail(function(){...});
回调函数中的data即为服务器返回的数据的一个代理,直接使用即可。
为了简化我们的开发jq提供了一些全局设置函数包括$.ajaxsetup()、$.()ajaxstart()、$().ajaxstop()、$().ajaxcomplete()、$().ajaxerror()、$().ajaxsuccess()、$().ajaxsend()。
$.ajaxsetup()用来设置基本的参数例如:
$.ajaxsetup({
type:"post",
contenttype:"application/json; charset=utf-8"
});
我们在使用$.ajax时可以直接这样设置:
$.ajax({
url:"",
success:function(){...},
error:function(){...}
})
最终等价于:
$.ajax({
type:"post",
contenttype:"application/json; charset=utf-8",
url:"",
success:function(){...},
error:function(){...}
})
$().ajaxstart()、$().ajaxstop()、$().ajaxcomplete()、$().ajaxerror()、$().ajaxsuccess()、$().ajaxsend()都是用来设置一些全局回调函数的。例如我们在提交数据时为了防止多次提交我们需要在发送请求时产生一个loading遮罩在数据发送完成后取消遮罩,如果在每一次ajax请求时我们都设置一次就会很麻烦,此时我们就可以用全局回调函数来简化我们的操作:
利用全局事件在请求开始时产生一个遮罩在请求完成时取消遮罩:
$(document).ajaxstart(function(){
loadingmask.show();
});
$(document).ajaxcomplete(function(){
loadingmask.hide();
});