同步和异步
同步:某一进程在请求服务器的时候这个进程会等待服务器返回的数据,接收到数据之后再继续执行其他操作,一般用在页面需要服务端数据返回才能正常运行的情况下。
异步:进程在请求服务器时,不等待服务器返回的数据,继续执行其他操作,一般用在不需要服务端数据就可以正常运行的程序中。
XMLHttpRequest对象的方法
方法 | 描述 |
abort() | 取消当前响应,关闭链接并且结束任何未解决的网络活动 |
getAllResponseHeaders() | 把HTTP响应头部作为未解析的字符串返回 |
getResponseHeader() | 返回指定的HTTP响应头部的值。 |
open() | 初始化HTTP请求参数,如URL和HTTP方法,但是并不发送请求 |
send() | 发送HTTP请求,使用传递给open()的方法的参数,以及传递给该方法的可选请求体 |
setRequestHeader() | 向一个打开但未发送的请求设置或添加一个http请求 |
// 实例代码 <script> // 首先创建XMLHttpRequest对象 var xmlhttp = null; if(window.XMLHttpRequest){ // 创建所有主流浏览器支持的XMLHttpRequest对象 xmlhttp = new XMLHttpRequest(); }else{ // 创建IE5和IE6支持的XMLHTTPRequest对象 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } // 初始化请求参数 xmlhttp.open('get','http://location:3000/3-3-1-get-data',true); // 设置请求头信息 xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencode"); // 发送请求 xmlhttp.send("name=Tome&age=18"); </script> // open() 方法用来初始化XMLHttpRequest对象,设置请求方式,URL,请求异步同步,该方法的格式open(method,url,ansyc,username,password) // method是get,post,put,delete,head // url 是我们请求的地址 // async是否请求异步 true是异步请求 false是同步请求 // username和password是可选的,为url所需的授权提供资格认证,如果指定了会覆盖之前的任何认证
注意:在调用open()方法的时候,readyState状态值会变成1,同时responseText,responseXML,status和statusText属性复位到他们的初始值
XMLHttpRequest对象的属性和事件
属性或事件 | 描述 |
readySate属性 | http的请求状态,当XMLHttpRequest()对象呗初次创建时,这个属性的值从0开始,知道接收到完整的http响应,这个值增加到4 |
onreadystatechange事件 | 每次readySate状态改变的时候调用的事件句柄函数。当readyState状态值为3时,是一个持续接收数据的过程 |
status属性 | 由服务器返回的http状态码,200表示成功,404表示not find。当readyState小于三的时候status会抛出一个异常。也就是说只有readyState是3的时候才会用到这个属性 |
statusText属性 | status返回了状态码,返回了与状态码对应的状态名称。属性是404的时候返回not found 当readyState小于三的时候会抛出异常 |
responseXML属性 | 对请求的响应,解析为Document对象返回。这个属性现在很少使用,使用json数据会更加方便 |
responseText属性 | 到目前为止(也就是这个属性被调用的时候),从服务器接收到的响应体。如果说readyState等于3时,说明只接受到头信息,响应体是空字符串,当readyState状态值为4的时候,表明数据接收完成 如果服务器响应头设定了字符集则采用,否则默认为Unicode UTF-8字符集 |
readySate状态值
状态值 | 名称 | 描述 |
0 | Uninitialized | 初始化状态。XMLHttpRequest对象以及创建或已被abort()方法重置 |
1 | Open | open()方法已被调用,但是send()方法未被调用。请求还没被发送 |
2 | Sent | send()方法已被调用,HTTP请求已发送到Web服务器,未接收到响应 |
3 | Receiving | 所有响应头部已经被接收到,响应体开始接收但是未完成 |
4 | Loaded | HTTP响应(所有的数据)已经被完全接收到 |
// XMLHttpRequest的详细流程 <!DOCTYPE html> <html> <head> <title>XMLHttpRequest</title> </head> <body> <h1>创建XMLHttpRequest对象</h1> <script type="text/javascript"> var xmlhttp = null; if(window.XMLHttpRequest){ // 主流浏览器 xmlhttp = new XMLHttpRequest(); // 弹出readyState值 alert('XMLHttpRequest对象创建时readyState的值为:'+xmlhttp.readyState); }else if(window.ActiveXObject){ // IE5.IE6创建XMLHttpRequest对象 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); // 弹出readystate的状态 alert('XMLHttpRequest对象创建时readyState的值为:'+xmlhttp.readyState); } var i = 1; // 每次readyState改变都会出发onreadystatechange事件 xmlhttp.onreadystatechange = function(){ // 验证readyState状态的改变,触发这个事件 if(xmlhttp.readyState === 1){ alert('open()方法执行完毕!readystate的值由0变为1!onreadystatechange第'+i++ +'次触发'); }else if(xmlhttp.readyState === 2){ alert('send()方法执行完毕!readystate的值由1变为2!onreadystatechange第'+i++ +'次触发'); }else if(xmlhttp.readyState === 3){ alert('接收响应头信息!readystate的值由2变为3!onreadystatechange第'+i++ +'次触发'); }else if(xmlhttp.readyState === 4 && xmlhttp.status === 200){ alert('接收响应数据体完成,readySate的值由3变为4'+i++ +'次触发'); // 弹出服务器响应状态 alert('服务器的响应状态码为:'+xmlhttp.status + '!响应状态文本为:'+xmlhttp.statusText); alert('服务器响应数据为:'+xmlhttp.responseText); // 弹出服务器的响应数据 }else{ // 请求失败处理 alert('服务器响应失败,失败的状态码为:'+xmlhttp.status+ '失败文本为:'+xmlhttp.statusText); } }; // 设置请求信息 xmlhttp.open('GET','http://localhost:3000/3-3-2-readyState-data',true); xmlhttp.send(); </script> </body> </html>
XMLHttpRequest对象
ajax的原理就是通过XMLHttpRequest对象向服务器发起异步请求,从服务器请求数据,然后通过JavaScript操作dom节点来更新数据。
GET请求实例和POST请求实例
代码示例(服务端):
// 服务器端代码 app.get('/3-4-1-post',function(req,res){ res.render('3-4-1-post'); }); // 3-4-1-post 答案的路由 app.post('/3-4-1-checkAnswer',function(req,res){ var data = req.body; if(data.answer1=="人生自古谁无死" && data.answer2=="留取丹心照汗青"){ res.send('正确'); }else{ res.send('错误'); } }); // 3-4-2查看答案的路由 app.get('/3-4-2-getAnswer',function(req,res){ res.json({answer1:'人生自古谁无死',answer2:'留取丹心照汗青'}); })
浏览器端:
<!DOCTYPE html> <html> <head> <title>发送ajax</title> </head> <body> <div class="title"> <h2>过零丁洋</h2> <h3>辛苦遭逢起一经,干戈寥落四周星。</h3> <h3>山河破碎风飘絮,身世浮沉雨打品。</h3> <h3>惶恐滩头说惶恐,零丁洋里叹伶仃。</h3> <input type="text" name="answer1" id="answer1">, <input type="text" name="answer2" id="answer2">。<br /><br /> <button onclick="putAnswer()">提交答案</button> <button onclick="getAnswer()">查看答案</button> <div id="showAnswer"></div> </div> <script type="text/javascript"> var xmlhttp = null; if(window.XMLHttpRequest){ // 创建所有主流浏览器支持的XMLHttpRequest对象 xmlhttp = new XMLHttpRequest(); }else if(window.ActiveXObject){ // 创建IE5和IE6的XMLHttpRequest对象 xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); } // 向服务器提交答案 function putAnswer(){ var answer1 = document.getElementById('answer1').value; var answer2 = document.getElementById('answer2').value; //onreadystatechange 事件 xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState === 4 && xmlhttp.status === 200){ var result = xmlhttp.responseText; alert('您的答案:'+result); } } xmlhttp.open("POST",'http://localhost:3000/3-4-1-checkAnswer',true); // 设置请求信息 // 设置请求头 xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); // 发送数据 xmlhttp.send('answer1='+answer1+'&answer2='+answer2); }; // 向服务器请求正确答案 function getAnswer(){ // onreadystatechange 事件 xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState == 4 && xmlhttp.status == 200){ var result = xmlhttp.responseText; // 获取服务器响应 var obj = JSON.parse(result); // 将服务器返回数据为json对象 //展示数据 document.getElementById('showAnswer').innerHTML = obj.answer1 +'?'+obj.answer2 +'.'; } } // 设置请求信息 xmlhttp.open("GET","http://localhost:3000/3-4-2-getAnswer",true); xmlhttp.send(); } </script> </body> </html>
封装AJAX对象
//封装ajax对象 function Ajax(){ var ajax = new Object(); //get请求方法 ajax.get = function(){ } // post 请求方法 ajax.post = function(){ } return ajax; }
封装GET方法
//创建XMLHTTPRequest对象 ajax.createXMLHttpRequest = function(){ // 定义空的xmlRequest对象 var xmlRequest = false; if(window.XMLHttpRequest){ // 主流 xmlHttpRequest = new XMLHttpRequest(); }else{ // IE5,IE6 xmlRequest = new ActiveXObject("Microsoft.XMLHTTP"); } return xmlRequest; } ajax.xmlRequest = ajax.createXMLHttpRequest();
// 处理同步或者异步 数据格式 function Ajax(dataType,async){ // 处理数据类型 ajax.dataType = dataType ? dataType.toUpperCase() : 'HTML'; // 处理同步异步 if(typeof(bool) == "undefined"){ ajax.async = true; }else{ ajax.async = async; } // onreadystatechange事件 ajax.changeFunction = function(){ if(ajax.xmlRequest.readyState == 4 && ajax.xmlRequest.status == 200){ if(ajax.dataType == 'HTML'){ ajax.callback(ajax.xmlRequest.responseText); }else if(ajax.dataType == 'JSON'){ // 处理json格式数据 ajax.callback(JSON.parse(ajax.xmlRequest.responseText)); }else if(ajax.dataType == 'XML'){ ajax.callback(ajax.xmlRequest.responseXML); } } } }
// get方法 ajax.get = function(url,callback){ if(callback != null){ // 便于使用onreadystatechange事件函数使用 ajax.callback = callback; // 调用onreadystatechange事件函数,把服务器返回的数据给回调函数 ajax.xmlRequest.onreadystatechange = ajax.changeFunction; } // 然后初始化GET请求 ajax.xmlRequest.open("GET",url,ajax.async); // 发送请求 ajax.xmlRequest.send(); }
封装POST方法
//post方法 /** Ajax中post请求方法 url请求的url endstring post请求携带的参数 字符串或json callback 用来接收服务器返回的回调函数 */ ajax.post = function(url,sendString,callback){ // 处理要向服务器提交的参数为xml支持的格式 if(typeof(sendString == 'boject')){ // 如果是json对象,转化成字符串 var str = ''; // 循环遍历这个对象 for(var key in sendString){ // 把json对象转化成name=Tom&age=19的形式 str += key + '=' + sendString[key] + '&'; } // 删除字符串最后一个‘&’ sendString = str.substr(0,str.length-1); } // 判断是否有回调函数,有回调函数的话调用onreadystatechange事件函数 if(callback != null){ // 把传递过来的回调函数给ajax的一个属性 // 便于onreadystatechange函数调用 ajax.callback = callback; // 调用onreadystatechange事件函数,把服务器返回的数据给回调函数 ajax.xmlRequest.onreadystatechange = ajax.changeFunition; } // 然后初始化post请求 ajax.xmlRequest.open("POST",url,ajax.async); // 设置post请求头信息 ajax.xmlRequestHeader('Content-Type','application/x-www-form-urlencoded'); ajax.xmlRequest.send(sendString); } return ajax; // 返回ajax对象 }