一、封装的思路
①写一个相对比较完善的用例
②写一个空函数,没有形参,将刚刚的用例直接作为函数体
③根据使用过程中的需求抽象参数
二、AJAX封装
①版本1.0:基本解决get和post方式的不同
<script> function ajax(method,url,params){ /* method参数传入方法,比如'GET','POST' url参数传入请求服务端地址,比如'test.php' params参数传入请求体所需传入的参数,比如 'id=1' , 'key1=value1&key2=value2' */ var xhr=new XMLHttpRequest(); if(method==='GET'){ url+='?'+params; } xhr.open(method,url); var data=null; if(method==='POST'){ xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); data=params; } xhr.send(data); xhr.onreadystatechange=function(){ if(this.readyState!==4) return; console.log(this.responseText); } } ajax('GET','test.php','id=1'); ajax('POST','test.php','key1=value1&key2=value2'); </script>
②版本2.0:解决第三个参数params,变为可以传入对象类型,以及get和post大小写的问题
<script> function ajax(method,url,params){ /* method参数传入方法,比如'GET','POST',可以忽略大小写 url参数传入请求服务端地址,比如'test.php' params参数传入请求体所需传入的参数,比如 'id=1' , 'key1=value1&key2=value2' params参数也可以传入对象类型的参数,比如{id:1},{key1:'value1',key2:'value2'} */ method=method.toUpperCase(); var xhr=new XMLHttpRequest(); //将object类型的参数转换为key1=value1&key2=value2 if(typeof params==='object'){ var tempArr=[]; for(var key in params){ var value=params[key]; tempArr.push(key+"="+value) } params=tempArr.join('&'); } if(method==='GET'){ url+='?'+params; } xhr.open(method,url); var data=null; if(method==='POST'){ xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); data=params; } xhr.send(data); xhr.onreadystatechange=function(){ if(this.readyState!==4) return; console.log(this.responseText); } } ajax('GET','test.php','id=1');//123 ajax('POST','test.php',{key1:'value1',key2:'value2'});//123 </script>
③版本3.0:尝试使函数有返回值,但是返回的是null,原因是异步模式下,onreadystatechange事件可能是最后执行完成的
<script> function ajax(method,url,params){ /* method参数传入方法,比如'GET','POST',可以忽略大小写 url参数传入请求服务端地址,比如'test.php' params参数传入请求体所需传入的参数,比如 'id=1' , 'key1=value1&key2=value2' params参数也可以传入对象类型的参数,比如{id:1},{key1:'value1',key2:'value2'} */ var res=null;//===================================== method=method.toUpperCase(); var xhr=new XMLHttpRequest(); //将object类型的参数转换为key1=value1&key2=value2 if(typeof params==='object'){ var tempArr=[]; for(var key in params){ var value=params[key]; tempArr.push(key+"="+value) } params=tempArr.join('&'); } if(method==='GET'){ url+='?'+params; } xhr.open(method,url); var data=null; if(method==='POST'){ xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); data=params; } xhr.send(data); xhr.onreadystatechange=function(){ if(this.readyState!==4) return; //无法通过内部包含的函数通过return返回外部函数的调用返回值 //return this.responseText; res=this.responseText;//====================================== } return res;//======================================== } var result=ajax('POST','test.php',{key1:'value1',key2:'value2'}); console.log(result);//null </script>
③版本4.0(完善版):引入回调函数解决问题
<script> /** *发送一个ajax请求 *@param (string) method请求方法 *@param (string) url 请求地址 *@param (object) params请求参数 *@param (Function) done 请求完成后需要做的事情(委托/回调) */ function ajax(method, url, params,done) { //统一转换为大写便于后续判断 method = method.toUpperCase(); //将对象类型的参数转换为urlencoded格式 var tempArr = []; for (var key in params) { tempArr.push(key + "=" + params[key]); } var querystring = tempArr.join('&'); var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Miscrosoft:XMLHTTP'); xhr.addEventListener('readystatechange',function(){ if(this.readyState!==4) return; //尝试通过JSON格式解析响应体 try{ done(JSON.parse(this.responseText)) }catch(e){ done(this.responseText) } }); //如果是GET请求设置URL地址问号参数 if(method==='GET'){ url+='?'+querystring; } xhr.open(method,url); //如果是POST请求就设置请求体 var data=null; if(method==="POST"){ xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); data=querystring; } xhr.send(data); } ajax('POST', 'test.php', {key1: 'value1',key2: 'value2'},function(data){ console.log(data); }); </script>