学习Ajax
Posted 法克大叔叔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Ajax相关的知识,希望对你有一定的参考价值。
1.XHR对象
IE7+、Firefox、Opera、Chrome和Safari都支持原生XMLHttpRequest对象,IE6不支持,只支持ActiveXObject对象,该对象在IE11中已经不再支持了。
IE中有三种不同版本的XHR对象MSXML2.XMLHTTP、MSXML2.XMLHTTP.3.0、MSXML2.XMLHTTP.6.0,所以可以通过一下函数创建一个兼容所有浏览器的XHR:
1 function createXHR() { 2 if(typeof XMLHttpRequest != "undefined"){ 3 return new XMLHttpRequest(); 4 }else if(typeof ActiveXObject != "undefined"){ 5 if(typeof arguments.callee.activeXString != "string"){ 6 var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len; 7 for(i=0,len=versions.length; i<len; i++){ 8 try { 9 new ActiveXObject(versions[i]); 10 arguments.callee.activeXString = versions[i]; 11 break; 12 }catch (ex){ 13 //跳过 14 } 15 } 16 } 17 return new ActiveXObject(arguments.callee.activeXString); 18 }else { 19 throw new Error("No XHR object available."); 20 } 21 }
或者简洁一点的:
1 if(typeof window.XMLHttpRequest != \'undefined\'){ 2 var xhr = new XMLHttpRequest(); 3 }else if(typeof window.ActiveXObject != \'undefined\'){ 4 var xhr = new ActiveXObject(\'Microsoft.XMLHTTP\'); 5}
也可以达到兼容ie的效果。
2.XHR用法
创建完XHR对象后可通过open方法启用一个请求,传入三个参数请求方法、url、是否异步(默认true)。调用完open方法后,请求并没有被发送,需要通过send()方法发送,发送时可附带一些请求数据,无需附带数据时传入null。通过readystatechange事件监听请求状态和http状态。通过responseText获取响应信息,或者通过responseType来设置响应信息的类型直接通过response属性获得响应数据来进行处理。
请求方式有两种GET、POST,get方式用于向服务器请求一些数据:
var btn = document.getElementById(\'btn\'); btn.onclick = function () { if(window.XMLHttpRequest != \'undefined\'){ var xhr = new XMLHttpRequest(); }else if(window.ActiveXObject != \'undefined\'){ var xhr = new ActiveXObject(\'Microsoft.XMLHTTP\'); } xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200){ alert(xhr.responseText); } } xhr.open("GET",\'data.txt\',true); //获取data.txt xhr.send(null); }
readyState为请求的状态码,每次状态变化都会触发readystatechange事件,通过监听该事件来判断是否成功收到响应。
0:未初始化
1:启用,调用了open方法
2:发送数据,调用了send
3:接收数据,但未完全接收
4:数据接收完毕,可以使用
当状态码为4的时候,服务器响应就完成了,但此时只是完成了响应,数据是否可用还要通过http的状态吗status来判断:
1xx:信息,服务器收到请求
2xx:成功,操作被成功接收并处理
3xx:重定向,需要进一步操做以完成请求
4xx:客户端错误,(404)请求资源地址不正确
5xx:服务器错误
当状态码为200是,则成功收到响应数据,所以只需判断status==200&&readyState==4就可以了。
get方式也可以发送少量数据,将数据附在url上传给服务器:
var btn = document.getElementById(\'btn\'); btn.onclick = function () { var text = encodeURIComponent(document.getElementById(\'active\').value); //用encodeURIComponent对字符串进行编码,会将多余的空格等进行转码 if(window.XMLHttpRequest != \'undefined\'){ var xhr = new XMLHttpRequest(); }else if(window.ActiveXObject != \'undefined\'){ var xhr = new ActiveXObject(\'Microsoft.XMLHTTP\'); } xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200){ alert(xhr.responseText); } } xhr.open("GET",\'test.php?active=\'+text,true);//将数据以键值对的形式附在url尾部,多个键值对之间用‘&’连接 xhr.send(null); }
PHP:
$active = $_GET[\'active\']; if($active == \'login\'){ echo \'{"key":"value"}\'; }else { echo \'error\'; }
但是get请求传递的数据都在url中所以安全性不高,需要发送数据一般用post请求,将请求数据通过send发送到服务器:
1 var btn = document.getElementById(\'btn\'); 2 btn.onclick = function () { 3 var text = encodeURIComponent(document.getElementById(\'active\').value); 4 5 if(window.XMLHttpRequest != \'undefined\'){ 6 var xhr = new XMLHttpRequest(); 7 }else if(window.ActiveXObject != \'undefined\'){ 8 var xhr = new ActiveXObject(\'Microsoft.XMLHTTP\'); 9 } 10 xhr.onreadystatechange = function() { 11 if(xhr.readyState == 4 && xhr.status == 200){ 12 alert(xhr.responseText); 13 } 14 } 15 16 xhr.open("POST",\'test.php\',true); 17 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置头信息,以表单的形式发送 18 var str=\'active=\'+text; 19 xhr.send(str); 20 }
使用post请求发送数据时,服务器并不会像处理表单一样来处理收到的数据,所以要在send之前并且在open之后要通过setRequestHeader设置头信息,告诉服务器这是表单。 从性能角度看,post请求消耗的资源更多一点,get请求速度更快。
3.超时设定
为XHR对象添加一个timeout属性来设置超时,当超过这个值时还未得到响应就会触发timeout事件并且会终止请求。
1 xhr.open("POST",\'test1.php\',true); 2 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 3 var str = \'active=\'+text; 4 xhr.timeout = 1; 5 xhr.ontimeout = function() { 6 alert("Request did not return in a second."); 7 } 8 xhr.send(str);
timeout属性和ontimeout事件要放在open之后send之前,不然ie会报错,并且只有ie8+支持。
4.进度事件
在浏览器接收新数据期间会周期性的触发progress事件。该事件接收一个event对象,对象包含三个二外属性:lengthComputable、loaded、total,分别表示进度信息是否可用,接收到的字节数和总字节数。下面是一个通过Ajax请求图片的例子:
1 <button id="btn">获取信息</button> 2 <div id="result"></div> 3 <div id="picture"></div> 4 <script> 5 btn.onclick = function(){ 6 //创建xhr对象 7 var xhr; 8 if(window.XMLHttpRequest){ 9 xhr = new XMLHttpRequest(); 10 }else{ 11 xhr = new ActiveXObject(\'Microsoft.XMLHTTP\'); 12 } 13 xhr.onprogress = function(e){//监听progress事件来显示接收进度 14 e= e || event; 15 if(e.lengthComputable){ 16 document.getElementById(\'result\').innerhtml = \'已接收:\'+e.loaded+\' /\'+e.total; 17 } 18 } 19 xhr.onreadystatechange = function(){ 20 if(xhr.readyState == 4 && xhr.status == 200){ 21 var data = xhr.response; 22 var img = document.createElement("img"); 23 img.src = URL.createObjectURL(data); //创建一个指向data的url 24 img.onload = function() { 25 URL.revokeObjectURL(img.src); 26 } 27 document.getElementById(\'picture\').appendChild(img); 28 } 29 } 30 xhr.open(\'GET\',\'RYH.png\',true); 31 xhr.responseType = \'blob\'; //响应数据类型为二进制数据 32 xhr.send(null); 33 } 34 </script>
这里的URL.createObjectURL(file | blob)传入一个file对象或blob(二进制对象)对象,创建一个指向该对象的URL。但是每次调用该方法时都会创建一个新的URL对象,即使指向的是同一个对象,所以每次创建完一个URL对象不再使用后要手动释放,通过URL.revokeObjextURL()来释放。
以上是关于学习Ajax的主要内容,如果未能解决你的问题,请参考以下文章