零基础学习AJAX之AJAX的简介和基础
本节简介(异步链接服务器对象)XMLHTTPRequest以及AJAX的简介。
AJAX即“AsynchronousJavascriptAndXML”(异步JavaScript和XML)。AJAX有四个方面的好处:1.即减轻了服务器的负担。2带来了更好的用户体验。3.基于标准被广泛的支持。4.拥有更好的页面呈现和数据分离。
技术名称 技术说明
javascript javascript是通用的脚本语言,AJAX是用javascript编写的
css 用户界面的样式通过css来修改
DOM DOM通过javascript修改DOM,ajax可以在运行时改变用户界面,或者局部更新页面中的某个节点。
XMLHttpRequest XMLHttpRequest对象XMLHttpRequest对象允许web程序员从web服务器以后台的方式获取数据。数据的个数通常是XML或者是文本。
从上面我们看出,javascript就想胶水一样将各个部分粘贴在一起,例如通过javascript操作BOM改变刷新用户界面,通过修改className来改变css样式风格
1.异步对象连接服务器
不严谨的说,ajax是一个简单的多线程,它能够是用户在前台多种操作而不间断。ajax异步交互在后台默默的工作着在web中异步访问是通过XMLHttpRequest对象来实现的,该对象最早是在ie5被作为activeX控件引入的。随后各个浏览器纷纷支持该异步对象,首先必须创建对象。代码如下:
varxmlHttp;
functioncreateXMLHrrpRequest(){
if(window.ActiveXObject)
xmlHttp=newActiveXObject("Microsoft.XMLHTTP");
elseif(window.XMLHttpRequest)
xmlHttp=newXMLHttpRequest();
}
该对象是先创建了一个全局变量xmlHttp,留以后函数中使用。另外创建异步对象函数createXMLHrrpRequest()
该过程用到了if语句方法,如果是IE采用window.ActiveXobject方法,如果不是,则用XMLHttpRequest方法创建函数。
在创建完异步对象后,自然是使用该对象连接服务器,该对象有一系列十分有用的属性和方法。
属性/方法 说明
abort() 取消请求
getAllResponseHeaders() 获取指定的Http头
open(method,url) 创建请求,method指定请求类型,GETPOST
send() 发送请求
setRequestHeader() 指定请求的http头
onreadystatechange 发生任何状态变化时的事件控制对象
readyState
请求的状态
0为尚未初始化
1为正在发送请求
2为请求完成
3为请求成功,正接收数据。
4为接收数据成功
responseText 服务器返回文本
responseXML 服务器返回xml
status
服务器返回的http请求响应值,常用的有
200表示请求成功
202表示请求被接收,但处理未完成
400表示错误的请求
404表示资源未找到
500表示内部服务器错误,如aspx代码错误
创建完XMLHttpRequest对象后首先利用open()方法建立一个请求,并向服务器发送,该方法的完整表示式如下:
open(methond,url,asynchronous,user,password)
其中,method表示请求的类型,通长为GET,POST。
url即请求的地址,可以是绝对地址,也可以是相对地址。
asynchronous是一个布尔值,表示是否为异步请求,默认值为异步请求true。
user、password分别为可选的用户名、密码。
创建了异步对象后,要建立一个到服务器的请求可使用如下代码:
xmlHttp.open("GET","1-1.aspx",true);
以上代码用get方法请求的相对地址为9-1.aspx的页面,方式是异步的。在发出了请求后便需要请求的状态readyState属性来判断请求的情况,如果该属性变化了,就会触发onreadystatechange事件,因此通常的代码如下:
<scripttype="text/javascript">
xmlHttp.onRecorderStateChange=function(){
if(xmlHttp.readyState==4)
//执行相关代码
}
</script>
也就是直接编写onRecorderStateChange的事件函数,如果readyState的状态为4(数据接收成功)则继续操作。但是通常情况下,不但需要判断请求的状态,还要判断服务器返回的状态status,因此上述代码改为
<scripttype="text/javascript">
xmlHttp.onRecorderStateChange=function(){
if(xmlHttp.readyState==4&&xmlHttp.status==200)
//执行相关代码
}
</script>
以上两段代码仅仅只是建立了请求,还需要使用send()方法来发送请求,该方法的原型如下:
send(body);
改方法仅有一个参数body,它表示要向服务器发送的数据,其格式为查询字符串的形式,例如:
varbody="myName=isaac&age=25";
如果再open中指定的是get方式,则这些参数作为查询字符串提交,如果指定的是post方式,则作为HTTP的POST方法提交。对于send()而言。body参数是必须的,如果不发送任何数据,则可以使用
xmlHttp.send(null)
特别的,如果使用POST方法进行提交请求,那么在发送之前必须使用以下语句来设置HTTP的头,语法如下:
xmlHttp.setRequestHeader("content-Type","application/x-www-form-urlencoded;")
服务器在收到客户端请求之后,根据请求返回相应的结果,这个结果通常为两种形式,一种是文本形式,存储在responseText中;另一种是XML格式,存储在responseXML中。客户端程序可以对前者进行字符串的处理,对后者进行DOM相关的处理,例如可以对服务器返回值做如下的处理:
alert("服务器返回:"+xmlHttp.responseText);
上述整个异步连接服务器的过程如下:
<body>
<scripttype="text/javascript">
varxmlHttp;
functioncreateXMLHttpRequest(){
if(window.ActiveXObject)
xmlHttp=newActiveXObject("Microsoft.XMLHTTP");
elseif(window.XMLHttpRequest)
xmlHttp=newXMLHttpRequest();
}
functionstartRequest(){
createXMLHttpRequest();
xmlHttp.open("GET","http://study.ahthw.com/ajaxresponse/1-1.aspx",true);
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4&&xmlHttp.status==200)
alert("服务器返回:"+xmlHttp.responseText);
}
xmlHttp.send(null);
}
</script>
<inputtype="button"value="测试异步通讯"onClick="startRequest()">
</body>
为了解决异步连接ie缓存问题,需要在真实地址加一个与时间毫秒相关的参数,使得每次请求的地址都不一样。而该参数服务器确是不需要的。
varsUrl="1-1.aspx?"+newDate().getTime();//地址不断变化
XMLHttp.open("GET",sUrl,true);
2.GET和POST模式
上面的实例中,除了请求异步服务器以外,并没有向服务器发送额外的数据,通常在html请求中有get和post模式,这两种模式都可以作为异步请求发送数据的方式。
如果是GET请求,则直接把数据放入异步请求的URL地址中,而send方法不发送任何数据,例如:
varqueryString="firstName=isaac&birthday=0226";
varsUrl="1-1.aspx?"+queryString+"×tamp"+newDate().getTime();
xmlHttp.open("GET",sUrl);
xmlHttp.send(null);//该语句只发送null
如果是POST模式,则是把数据统一在send()方法中送出,请求地址没有任何信息,并且必须设置请求的文件头,例如:
<scriptlanguage="javascript">
varqueryString="firstName=isaac&birthday=0226";
varsUrl="1-1.aspx?"+queryString+"×tamp"+newDate().getTime();
xmlHttp.open("POST",sUrl);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttp.send(queryString);//该语句负责发送数据
</script>
实例
为了更清楚地演示GET和POST的区别,编写示例代码,首先创建两个文本框用于输入用户姓名和生日,并建立两个按钮分别用于GET和POST两个方法来发送异步请求
<form>
<p><inputtype="text"id="firstName"/></p>
<p><inputtype="text"id="birthday"/></p>
</form>
<inputtype="button"value="GET"onClick="doRequestUsingGET()">
<inputtype="button"value="POST"onClick="doRequestUsingPOST()">
其中用户填写的数据统一用函数createQueryString()编写,需要时予以调运,代码如下
functioncrrateQueryString(){
varfirstName=document.getElementById("firstName").value;
varbirthday=document.getElementById("birthday").value;
varqueryString="firstName="+firstName+"&birthday="+birthday;
returnqueryString;
}
服务器接收到请求数据后根据不同的时刻返回相应的文本,客户端接收到文本后显示在相应的div快中,代码如下
functionhandleStateChange(){
if(xmlHttp.readyState==4&&xmlHttp.state==200){
varresponseDiv=document.getElementById("serverResponse");
responseDiv.innerHTML=xmlHttp.responseText;
}
}
GET和POST各建立自己的函数doRequestUsingGET()和doRequestUsingPOST()。
完整代码如下:
<scripttype="text/javascript">
varxmlHttp;
functioncreateXMLHttpRequest(){
if(window.ActiveXObject)
xmlHttp=newActiveXObject("Microsoft.XMLHttp");
elseif(window.XMLHttpRequest)
xmlHttp=newXMLHttpRequest();
}
functioncreateQueryString(){
varfirstName=document.getElementById("firstName").value;
varbirthday=document.getElementById("birthday").value;
varqueryString="firstName="+firstName+"&birthday="+birthday;
returnencodeURI(encodeURI(queryString));//两次编码解决中文乱码问题
}
functiondoRequestUsingGET(){
createXMLHttpRequest();
varqueryString="1-3.aspx?";
queryString+=createQueryString()+"×tamp="+newDate().getTime();
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.open("GET",queryString);
xmlHttp.send(null);
}
functiondoRequestUsingPOST(){
createXMLHttpRequest();
varurl="1-3.aspx?timestamp="+newDate().getTime();
varqueryString=createQueryString();
xmlHttp.open("POST",url);
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttp.send(queryString);
}
functionhandleStateChange(){
if(xmlHttp.readyState==4&&xmlHttp.status==200){
varresponseDiv=document.getElementById("serverResponse");
responseDiv.innerHTML=decodeURI(xmlHttp.responseText);//解码
}
}
</script>
<form>
<inputtype="text"id="firstName"/>
<br>
<inputtype="text"id="birthday"/>
</form>
<form>
<inputtype="button"value="GET"onclick="doRequestUsingGET();"/>
<br>
<inputtype="button"value="POST"onclick="doRequestUsingPOST();"/>
</form>
<divid="serverResponse"></div>
服务器端主要是根据用户输入以及请求的类型返回不同的字符串
<%@PageLanguage="C#"ContentType="text/html"ResponseEncoding="gb2312"%>
<%@ImportNamespace="System.Data"%>
<%
if(Request.HttpMethod=="POST")
Response.Write("POST:"+Request["firstName"]+",yourbirthdayis"+Request["birthday"]);
elseif(Request.HttpMethod=="GET")
Response.Write("GET:"+Request["firstName"]+",yourbirthdayis"+Request["birthday"]);
%>
从以上代码看出POST和GET都发送了数据异步请求,通常在数据不多的时候使用GET,在数据较多的时候使用POST。
在使用PSOT发送中文字符时,post接收会乱码,使用GET发送中文字符正常。这是因为异步对象xmlHttp在处理返回的responseText的时候,是按照UTF-8编码的。
通常的解决办法是escape()对发送的数据进行编码,然后在返回的responseText再使用unescape()进行解码。然而在javascript编程中通常不推荐escape()和unescape()。而推荐使用encodeURI()和decodeURI()。这里要正常运行,必须对发送的数据进行两次encodeURI()编码。
代码如下
functioncreateQueryString(){
varfirstName=document.getElementById("firstName").value;
varbirthday=document.getElementById("birthday").value;
varqueryString="firstName="+firstName+"&birthday="+birthday;
returnencodeURI(encodeURI(queryString));//两次编码解决中文乱码问题
}
而且在返回数据responeText时再进行一次解码,代码如下
functionhandleStateChange(){
if(xmlHttp.readyState==4&&xmlHttp.status==200){
varresponeDiv=document.getElementById(serverResponse);
responeDiv.innerHTML=decodeURI(XMLHttp.responseText);//编码
}
}
这样POST模式下也能使用中文了。
3.服务器返回xml
XML是一种可扩展标记语言(ExtensibleMarkupLanguage),它是一种可自定义标记的语言,用来克服html局限,按照实际功能来看,xml主要用于数据存储。
在ajax中,服务器如果返回XML,可通过异步对象的responseXML属性来获取,开发者可以利用DOM的作用方法进行处理。
假设服务器返回
<?xmlversion="1.0"encoding="gb2312"?>
<list>
<caption>MemberList</caption>
<member>
<name>isaac</name>
<class>W13</class>
<birth>Jun24th</birth>
<constell>Cancer</constell>
<mobile>1118159</mobile>
</member>
<member>
<name>fresheggs</name>
<class>W610</class>
<birth>Nov5th</birth>
<constell>Scorpio</constell>
<mobile>1038818</mobile>
</member>
<member>
<name>girlwing</name>
<class>W210</class>
<birth>Sep16th</birth>
<constell>Virgo</constell>
<mobile>1307994</mobile>
</member>
<member>
<name>tastestory</name>
<class>W15</class>
<birth>Nov29th</birth>
<constell>Sagittarius</constell>
<mobile>1095245</mobile>
</member>
<member>
<name>lovehate</name>
<class>W47</class>
<birth>Sep5th</birth>
<constell>Virgo</constell>
<mobile>6098017</mobile>
</member>
<member>
<name>slepox</name>
<class>W19</class>
<birth>Nov18th</birth>
<constell>Scorpio</constell>
<mobile>0658635</mobile>
</member>
<member>
<name>smartlau</name>
<class>W19</class>
<birth>Dec30th</birth>
<constell>Capricorn</constell>
<mobile>0006621</mobile>
</member>
<member>
<name>tuonene</name>
<class>W210</class>
<birth>Nov26th</birth>
<constell>Sagittarius</constell>
<mobile>0091704</mobile>
</member>
<member>
<name>dovecho</name>
<class>W19</class>
<birth>Dec9th</birth>
<constell>Sagittarius</constell>
<mobile>1892013</mobile>
</member>
<member>
<name>shanghen</name>
<class>W42</class>
<birth>May24th</birth>
<constell>Gemini</constell>
<mobile>1544254</mobile>
</member>
<member>
<name>venessawj</name>
<class>W45</class>
<birth>Apr1st</birth>
<constell>Aries</constell>
<mobile>1523753</mobile>
</member>
<member>
<name>lightyear</name>
<class>W311</class>
<birth>Mar23th</birth>
<constell>Aries</constell>
<mobile>1002908</mobile>
</member>
</list>
下面利用异步对象获取该XML,并将所有的项都罗列在表格中,初始化对象的方法与获取文本完全相同,代码如下:
varxmlHttp;
functioncreateXMLHttpRequest(){ if(window.ActiveXObject) xmlHttp=newActiveXObject("Mincrosoft,XMLHttp"); elseif(window.XMLHttpRequest) xmlHttp=newXMLHttpRequest(); }