一、封装
当我们做项目的时候,可能会在很多地方需要使用AJAX来完成需求,虽然即便是写原生的AJAX也并不算太复杂,但如果每次都重复那几个套路化的步骤还是挺烦人的,所以我们的第一反应就是封装。
对,把这些套路化的代码封装起来。这里的代码当然是指客户端的,那段使用Javascript语言,实现AJAX基本get/post请求的代码。
直接上代码吧,一边看一边说。
function ajax(jsonData){ //jsonData = { // data:"", //客户端发送给服务端的参数,形式是"key1=val1&key2=val2 ... " // dataType:"xml/json", //客户端预接收服务端响应报文数据格式 // type:"get/post", //http请求方式 // url:"/MyHandler.ashx", //请求地址 // asyn:"true/false", //是否使用异步方式发送请求 // success:function(){}, //正常获取到响应报文之后的回调函数 // failure:function(){} //发生异常的回调函数 // } var xhr = null; if(window.XMLHttpRequest){//标准的浏览器 xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //配置参数 var type = jsonData.type == 'get'?'get':'post'; var url = ''; if(jsonData.url){ url = jsonData.url; if(type == 'get'){ url += "?" + jsonData.data; } } var flag = jsonData.asyn == 'true'?'true':'false'; xhr.open(type,url,flag); //指定回调函数 xhr.onreadystatechange = function(){ if(this.readyState == 4 && this.status == 200){ if(typeof jsonData.success == 'function'){ var d = jsonData.dataType == 'xml' ? xhr.responseXML : xhr.responseText; jsonData.success(d); } }else{ if(typeof jsonData.failure == 'function'){ jsonData.failure(); } } } }
//发送请求 if(type == 'get'){ xhr.setRequestHeader("If-Modified-Since","0"); xhr.send(null); }else if(type == 'post'){ xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.send(jsonData.data); } }
这个名为ajax的方法封装了两种异步请求的方式,分别是get和post。所谓封装,就是把不变的部分写在方法内部,把会变化的部分封装成方法的参数,由调用者在调用该方法时,临时指定这些参数。所以,先来解释下ajax(jsonData)方法中的参数。
顾名思义,这个参数是json格式的。
那么问题来了,为什么是json?为啥不能搞成好几个简单类型的参数?比如把方法封装成这个样子:ajax(url,type,data,dataType,success)
首先,我不得不承认,封装成这个样子肯定也是没问题的。至于为啥要给个json格式对象,恕我理论水平不高,我仅仅能给出以下3个解释
1.从面向对象的思维方式来说,每次调用ajax()方法都是一次独立的请求,那么每次独立的请求就应该是一个完整的整体,基于这个逻辑,调用的参数也应该是一个整体,而javascript中没有类的概念,不过幸好有json格式的对象,正好满足了我们对面向对象编程思维方式的”内在要求“。
2.美观,优雅。对,你没看错,我不是搞化妆的,我是在说代码。你不觉得这样的json对象传递过去后代码更美观、优雅?
3.jQuery的原因。jQuery是一个重要的插件,它为我们提供的,实现AJAX的api,所需要的参数就是json格式。聪明的同学已经猜到了,我们这个ajax函数就是在模拟jQuery中的$.ajax()方法,没错,不仅仅是模拟,简直就是抄袭,连这个json对象中的key的名字都一模一样,为了让大家容易理解,我也是拼了。
好了,还是说下参数的各个key&value都代表什么意思吧。
//jsonData = { // data:"", //客户端发送给服务端的参数,形式是"key1=val1&key2=val2 ... " // dataType:"xml/json", //客户端预接收服务端响应报文数据格式 // type:"get/post", //http请求方式 // url:"/MyHandler.ashx", //请求地址 // asyn:"true/false", //是否使用异步方式发送请求 // success:function(){}, //正常获取到响应报文之后的回调函数 // failure:function(){} //发生异常的回调函数 // }
看懂了吗?没看懂吗??这还看不懂?
接下来的代码部分就是根据请求方式的不同[get/post],来发出请求,此两种方式的区别就在于以下3点:
1.在调用open函数时,设置的请求方式参数不同,一个是“get",一个是”post“
2.在发出请求时,往服务端发送参数的方式不同,一个在url后边拼写参数,另一个要把参数放在send函数的圆括号内。
3.需要设置的请求报文头不一样。
我相信只要从头看本系列的同学肯定不需要我解释什么了。
最后就是看调用了
window.onload = function(){ //注册按钮单击事件 var btn = document.getElementById('btn'); btn.onclick = function(){ var param = { url:'myHandler.ashx', type:'get', dataType:'json', success:function(data){ alert(data); } }; ajax(param); } }
二、jQuery的异步api
如果你看明白了上面的封装,那么你只需要记住2句话就记住jQuery的异步api了。
1.jQuery封装了好几个用于异步刷新的api,但核心只有1个,就是:$.ajax(data)函数。其他的api都是在这个的基础上2次封装的
2.$.ajax(data)与上边分装的 ajax(jsonData) 是一模一样的。唯一的区别就是人家的代码更严谨,传递的参数,也就是那个json对象的key更多,说白了就是能设置更多的信息。
that's all
最后把$.ajax()的参数晒出来,这里只晒最常用的key。
- url: 要求为String类型的参数,发送请求的地址(默认为当前页地址)。
- type: 要求为String类型的参数,请求方式,默认为get。
- async:要求为Boolean类型的参数,表示是否使用异步方式发送请求,默认设置为true。
- cache:要求为Boolean类型的参数,表示是否从浏览器缓存中加载请求信息。设置为false将不会从浏览器缓存中加载请求信息,默认为true(当dataType为script时,默认为false)
- data: 要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。
- dataType: 要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http响应报文头中mime信息返回responseXML或responseText,并作为回调函数参数传递。备选项有:text、xml、html、script、json、jsonp
- contentType:要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
- success:要求为Function类型的参数,请求成功后调用的回调函数,原型为:function(data, textStatus){}。该回调函数有两个参数。其中data表示服务端返回的数据,textStatus表示描述状态的字符串(此参数很少使用)
- error:要求为Function类型的参数,请求失败时被调用的函数。
- jsonp:
这里只有一个key我们看起来陌生,就是最后一个jsonp,这恰好是我们下一次的主题。
jsonp ,I‘m coming。