ajax的原生实现-XMLHttpRequest
ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。当初JavaScript的变革就是ajax的出现而改变。在现代web领域对数据的异步加载和局部更新上也在大量采用ajax这项技术。
目前浏览器在使用ajax技术上都是使用XMLHttpRequest(XHR)对象来对服务器进行交互。对于IE低版本(6/7)上则是使用的另一种实现方式(ActiveXObject),我们可以从URL获取数据,而不用让整个页面刷新,从而实现局部刷新。这样请求的次数也会大大减少,有效节约资源浪费。XMLHttpRequest的交互原理则是XMLHttpRequst请求事件目标(XMLHttpRequestEventTarget)从而到达后端事件目标。事件目标对请求事件进行验证实现业务逻辑,最后可以响应处理结果与前端交互。XMLHttpRequest不光能请求XML类型的数据(文本、图片、html,信息流等),同样还支持HTTP以外的协议,比如文件流和ftp等等。类似的还有WebSockets(全双工通信),Server-Sent event(HTML5服务器发送事件)。
目前浏览器在使用ajax技术上都是使用XMLHttpRequest(XHR)对象来对服务器进行交互。对于IE低版本(6/7)上则是使用的另一种实现方式(ActiveXObject),我们可以从URL获取数据,而不用让整个页面刷新,从而实现局部刷新。这样请求的次数也会大大减少,有效节约资源浪费。XMLHttpRequest的交互原理则是XMLHttpRequst请求事件目标(XMLHttpRequestEventTarget)从而到达后端事件目标。事件目标对请求事件进行验证实现业务逻辑,最后可以响应处理结果与前端交互。XMLHttpRequest不光能请求XML类型的数据(文本、图片、html,信息流等),同样还支持HTTP以外的协议,比如文件流和ftp等等。类似的还有WebSockets(全双工通信),Server-Sent event(HTML5服务器发送事件)。
XMLHttpRequest对象的使用
在使用XMLHttpRequest
之前我们需要初始化一个XMLHttpRequest
对象,才能使用它的属性和方法。
常用方法和属性:
// 初始化对象,将最先调用该对象的构造函数 var oReq = new XMLHttpRequest(); oReq.open(method,url,async); // 初始化一个请求,例如 oReq.open('GET',url,true) ++++++++++++++++++++++++++++++++++++++++++ function reqListener () { console.log(this.responseText); } var oReq = new XMLHttpRequest(); oReq.onload = reqListener; // 请求加载完成调用此方法 oReq.open("get", "yourFile.txt", true); oReq.send(); // XMLHttpRequest同样也支持多种时间绑定,第一个参数为触发时间,第二个参数为绑定执行函数 var req = new XMLHttpRequest(); req.addEventListener("progress", updateProgress, false); req.addEventListener("load", transferComplete, false); req.addEventListener("error", transferFailed, false); req.addEventListener("abort", transferCanceled, false); req.open(); //注意:必须在open()之前添加事件监听,否则progress(进度)事件将不会被触发 // 此外XMLHttpRequest还能够接收二进制数据,具体操作可以阅读相关文档 var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder || window.BlobBuilder; var oReq = new XMLHttpRequest(); oReq.open("GET", "/myfile.png", true); oReq.responseType = "arraybuffer"; oReq.onload = function(oEvent) { var blobBuilder = new BlobBuilder(); blobBuilder.append(oReq.response); var blob = blobBuilder.getBlob("image/png"); // ... }; oReq.send(); +++++++++++++++++++++++++++++++++++++++++++++ oReq.setRequestHeader(header,value); //针对post方法需要设置头部信息才能有效解析参数 oReq.setRequestHeader('content-type','application/x-www-form-urlencoded'); oReq.send()方法,如果是get协议可以为空,但是如果是post协议,则传递给服务端的参数需要在这里面指定 xhr.send("foo=bar&lorem=ipsum"); // post表单数据可以通过for/in拼接字符串来进行 // xhr.send('string'); // xhr.send(new Blob()); // xhr.send(new Int8Array()); // xhr.send({ form: 'data' }); // xhr.send(document); oReq.onreadystatechange = fn; // 在readyStatus属性状态发生改变时触发 // 当readyStatus就绪状态发生改变时调用函数,状态有0-4 xhr.onreadystatechange = function() { if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) { // 请求结束后,在此处写处理代码 } } oReq.response // 返回响应的正文,它和reponseText的区别是,response还可以是其他类型的数据,不光是文本类型 oReq.responseText // 请求成功会返回一个响应的字符串,如果发送失败或未发送则返回null var xhr = new XMLHttpRequest(); xhr.open('GET', '/server', true); // If specified, responseType must be empty string or "text" xhr.responseType = 'text'; xhr.onload = function () { if (xhr.readyState === xhr.DONE) { if (xhr.status === 200) { console.log(xhr.response); console.log(xhr.responseText); } } }; xhr.send(null); // 返回一个无符号请求响应状态,比如 200,304,501,404 oReq.status 其他属性和方法我们可以打印XMLHttpRequest对象或者参考官方文档来进行使用
get方式
需要注意缓存问题和编码,针对中文可以使用url编码工具进行处理,对于缓存问题可以使用添加时间随机数来解决。
var xhr = new XMLHttpRequest(); // 第三个参数为true则使用异步I/O处理方式,fase为同步I/O处理方式(阻塞式,在没有响应数据返回时程序会等待) xhr.open('get','index.php?username'+encodeURI('严总')+'&age=30&'+ new Date().getTime(),true); xhr.send(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ consoel.log(xhr.responseText); } else { console.log('status:'+xhr.status); return false; } };
post方式:
声明了请求头之后会自动进行编码,也没有缓存问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> </style> </head> <body> <input type="button" id="btn" value="request"> </body> <script> var oBtn = document.querySelector('#btn'); var userData = { username:'boole', age:30, address:'china' }; oBtn.addEventListener('click',function(){ var xhr = null; // 兼容低版本IE,这里使用异常处理分支完成,防止报错阻断程序运行 try{ xhr = new XMLHttpRequest(); } catch(e){ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } xhr.open('post','index.php',true); xhr.setRequestHeader('content-type','application/x-www-form-urlencoded'); xhr.send(changeData(userData)); xhr.onreadystatechange = function(){ if(xhr.readyState ==4){ console.log(xhr.responseText); //字符串形式的响应数据需要进行转换成对象才能使用 console.log(JSON.parse(xhr.responseText).username); // 也可以使用eval预执行的方式进行转换 var responseData = eval('('+xhr.responseText+')'); for(item in responseData){ console.log(item + '=' + responseData[item]); } } else { console.log(xhr.status); } }; }); function changeData(oData){ var str = ''; for(item in oData){ str += '&' + item + '=' + oData[item]; } return str.slice(1); } </script> </html>
后台在接收到数据之后,在返回数据的时候可以使用json的格式进行返回(例如:echo json_encode($arr);)
注意: 后端返回的responseText总是字符串格式,直接使用属性方法是不能获取到数据的,我们需要对响应的数据进行格式转换。
方法有两种,如果后端返回的是json格式的,那么XMLHttpRequest接收的时候回转换成字符串形式的,
我们可以使用JSON.parse(str) 和 eval('('+str+')')进行转换成json对象的形式,这样一来我们就可以使用for/in对数据进行迭代处理。可以动态更新页面数据
// 此处回提示undefined,因为是字符串形式的数据 console.log(xhr.responseText.username); // 转换方式一 var reponseData = JSON.parse(xhr.responseText); // 抓换方式二 var reponseData = eval('('+xhr.responseText+')');
XMLHttpRequest函数的封装
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <style> </style> </head> <body> <input type="button" id="btn" value="request" /> <ul id="ul"></ul> <script> var oBtn = document.querySelector('#btn'); var userData = { username:'boole', age:30, address:'china' }; oBtn.addEventListener('click',function(){ // 定时请求局部更新 setInterval( ajax('post','index.php',userData,function(data){ var data = JSON.parse(data); var oUl = document.querySelector('#ul'); var aLi = ''; for (item in data){ aLi +='<li>' + item + '[' + data[item] + ']</li>'; } oUl.innerHTML = aLi,document.innerHTML = oUl; }),2000 ); }); // ajax函数封装,对可变数据设置形参 function ajax(method,url,data,success){ var str = '',xhr = null; if(data instanceof Array || (typeof data == 'string')){ console.log('parameter type error'); return false; } else { for(item in data){ str += '&' + item + '=' + data[item]; } str = str.slice(1); } console.log(str); // 兼容低版本IE,这里使用异常处理分支完成,防止报错阻断程序运行 try{ xhr = new XMLHttpRequest(); } catch(e){ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } if(method == 'get' && data){ url += '?' + str + '&' + new Date().getTime(); } xhr.open(method,url,true); if(method == 'get'){ xhr.send(); } else { xhr.setRequestHeader('content-type','application/x-www-form-urlencoded'); xhr.send(str); } xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ console.log(xhr.responseText); success && success(xhr.responseText); } else { alert('请求失败,状态码:'+ xhr.status); } } }; } </script> </body> </html>
相关推荐
jiaguoquan00 2020-07-07
坚持着执着 2020-06-05
坚持着执着 2020-06-16
风萧萧梦潇 2020-06-06
88570299 2020-06-05
kentrl 2020-11-10
结束数据方法的参数,该如何定义?-- 集合为自定义实体类中的结合属性,有几个实体类,改变下标就行了。<input id="add" type="button" value="新增visitor&quo
ajaxyan 2020-11-09
zndy0 2020-11-03
学留痕 2020-09-20
Richardxx 2020-11-09
learningever 2020-09-19
chongxiaocheng 2020-08-16
ajaxhe 2020-08-16
lyqdanang 2020-08-16
curiousL 2020-08-03
TONIYH 2020-07-22
时光如瑾雨微凉 2020-07-19
83510998 2020-07-18