J2EE从入门到精通4041Ajax.docx
《J2EE从入门到精通4041Ajax.docx》由会员分享,可在线阅读,更多相关《J2EE从入门到精通4041Ajax.docx(83页珍藏版)》请在冰点文库上搜索。
J2EE从入门到精通4041Ajax
40Ajax
AJAX指异步JavaScript及XML(AsynchronousJavaScriptAndXML)。
国内翻译常为“阿贾克斯”和阿贾克斯足球队同音。
Web应用的交互如Flickr,Backpack和Google在这方面已经有质的飞跃。
这个术语源自描述从基于Web的应用到基于数据的应用的转换。
在基于数据的应用中,用户需求的数据如联系人列表,可以从独立于实际网页的服务端取得并且可以被动态地写入网页中,给缓慢的Web应用体验着色使之像桌面应用一样。
Ajax的核心是JavaScript对象XmlHttpRequest。
该对象在InternetExplorer5中首次引入,它是一种支持异步请求的技术。
简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。
40.1AsynchronousJavaScript+XML
Ajax这个名词是由JesseJamesGarrett提出,在他发表的Ajax:
ANewApproachtoWebApplications这篇文章中谈到GoogleSuggest与GoogleMaps所使用到的技术,是他们在AdaptivePath中称之为Ajax的新方法:
GoogleSuggestandGoogleMapsaretwoexamplesofanewapproachtowebapplicationsthatweatAdaptivePathhavebeencallingAjax.ThenameisshorthandforAsynchronousJavaScript+XML,anditrepresentsafundamentalshiftinwhat’spossibleontheWeb.
在文中指出,Ajax是AsynchronousJavaScript+XML的简称,这指出了Ajax的核心观念(Asynchronous)与所使用到的主要两个技术(JavaScript、XML)。
Asynchronous为非同步,要了解Ajax,必须先了解为何要非同步。
现在许多的应用程式都是在Web上展现,这托了网际网路的普及之福,然而网路当初是Web应用程式繁荣的舞台,现在却也成了限制Web应用程式发展的因素。
限制的原因来自于网路延迟的不可确定性,网路连线其实是个很耗资源的行为,程式必须序列化、通讯协定沟通、实体路由传送等动作,这些动作都很耗时间与资源,所有透过网路必需的额外操作,常足以拖慢一个系统,就Web应用程式而言,通常只能透过表单进行资料提交,在同步的情况下,使用者送出表单之后,就只能等待远端伺服器回应,在这段时间内,使用者无法作进一步的操作。
上图中阴影部份为送出表单之后,使用者必须等待的时间,浏览器预设是使用同步的方式送出请求并等待回应,这也可以想像成存取一个很慢的硬碟,如果这是桌面应用程式,您就可以想像这种等待有多枯燥,人们之所以可以忍受Web应用程式的这种等待,某些原因是因为无从选择而习惯了。
如果可以把请求与回应改为非同步进行,也就是发出请求后,浏览器无需苦等伺服器的回应,而可以让使用者对浏览器中的Web应用程式进行其它的操作,当伺服器终于处理完请求并送出回应,而电脑接收到回应时,再回过头来呼叫浏览器所设定的对应动作进行处理。
现在的问题是,谁来发送非同步请求,事实上有几种解决方案,在Ajax这个名词被提出之前,早就有着用IFrame的方式,也就是在HTML页面中内嵌另一个HTML页面,由内嵌的页面来发出请求,而外围的HTML页面还是可以继续让使用者进行操作,有时候IFrame的解决方式会是简单的,甚至比较好的。
不过现在谈到Ajax,都着重在XMLHttpRequest对象,您可以使用JavaScript来建立,其实Firefox、NetScape、Safari、Opera中才叫XMLHttpRequest,InternetExplorer中是Microsoft.XMLHTTP或Msxml2.XMLHTTP的ActiveX对象,不过IE7中也正名为XMLHttpRequest。
Ajax应用程式是必须由客户端、伺服端一同合作的应用程式,JavaScript是用来撰写Ajax应用程式客户端的语言,XML则是请求时或回应时,建议使用的交换资料格式,Ajax的客户端与伺服端基本上是可以独立开发的,只要协议好沟通的资料格式,伺服端不限于使用何种技术。
您可能正在使用CyberArticle破解版本,该版本可能会导致无法完整保存网页(例如不能保存Flash,图片...)。
请点击这里,购买正式版本(注册费仅需人民币25元),可以解决这个问题。
40.2XMLHttpRequest
在Ajax应用程式中,如果是Mozilla/Firefox/Safari中,可以透过XMLHttpRequest来发出非同步请求,如果是在IE6或IE先前版本,则是使用ActiveXObject来发出非同步请求,为了各个不同浏览器间的相容性,必须进行测试可取得XMLHttpRequest或ActiveXObject,例如:
varxmlHttp;
functioncreateXMLHttpRequest(){
if(window.XMLHttpRequest){//如果可以取得XMLHttpRequest
xmlHttp=newXMLHttpRequest();//Mozilla、Firefox、Safari
}
elseif(window.ActiveXObject){//如果可以取得ActiveXObject
xmlHttp=newActiveXObject("Microsoft.XMLHTTP");//InternetExplorer
}
}
这段程式码可以满足大部份的浏览器,您可以再进一步检查是否真正生成了对象,例如:
if(xmlHttp){
//dorequest
}
else{
alert("您的浏览器不支援这个Ajax程式的功能");
}
在建立XMLHttpRequest之后,则可以使用以下的几种方法:
voidopen(stringmethod,stringurl,booleanasynch,stringusername,stringpassword)
开启对伺服端的连结;method为请求方式(GET、POST);url为伺服端位址,如果是GET的话,可加上请求参数与值;asynch为非同步设定,预设是true,表示使用非同步方式。
voidsend(content)
对伺服端传送请求,content这以放XML、输入串流、字串、JSON格式的内容,放进去会放在POST本体中发送。
voidsetRequestHeader(stringheader,stringvalue)
为HTTP请求设定一个给定的header设定值。
voidabort()
用来中断请求。
stringgetAllResponseHeaders()
传回一个字串,其中包含HTTP请求的所有回应标头。
stringgetResponseHeader(stringheader)
传回一个字串,其中包含指定的回应标头值。
XMLHttpRequest包括以下几个标准属性:
onreadystatechange
参考至callback函式,readyState每次改变时,都会呼叫onreadystatechange所参考的函式。
readyState
会有0到4的数值,分别表示不同的请求状态:
0=未初始化的连线(uninitialized),还没呼叫open()
1=载入中(loading),呼叫open(),还没呼叫send()
2=已载入(loaded),呼叫send(),请求header/status准备好
3=互动中(interactive),正在与伺服器互动中
4=请求完成(completed),完成请求
responseText
伺服器传来的请求回应文字,会设定给这个属性。
responseXML
伺服器传来的请求回应如果是XML,会成为DOM设定给这个属性。
status
伺服器回应的状态码,例如200是OK,404为NotFound…
statusText
伺服器回应的状态文字。
一个基本的Ajax请求可以是以下的片段:
functionstartRequest(){
createXMLHttpRequest();//建立非同步请求对象
xmlHttp.onreadystatechange=handleStateChange;//设定callback函式
xmlHttp.open("GET","simpleResponse.txt");//开启连结
xmlHttp.send(null);//传送请求
}
functionhandleStateChange(){//在这边处理非同步回应
…
}
当每次readyState改变时,都会呼叫以上程式片段中设定的handleStateChange()函式,通常会在请求完成进行处理,所以您可以如以下的程式片段来处理回应:
functionhandleStateChange(){
if(xmlHttp.readyState==4){//测试状态是否请求完成
if(xmlHttp.status==200){//如果伺服端回应OK
alert("伺服器回应"+xmlHttp.responseText);//这边只取得回应文字
}
}
}
40.3AjaxGossip:
Hello!
Ajax!
来编写您第一个Ajax程序,使用非同步的方式向服务端取得数据,并加以显示,首先请准备一个HTML网页:
HelloAjaxEx-1.html
DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
Hello!Ajax!
Examples...
这个HTML网页会取得JavaScript文件,而按下按钮后,会执行startRequest()函式,JavaScript文件如下所示:
HelloAjaxEx-1.js
varxmlHttp;
functioncreateXMLHttpRequest(){
if(window.XMLHttpRequest){
xmlHttp=newXMLHttpRequest();
}
elseif(window.ActiveXObject){
xmlHttp=newActiveXObject("Microsoft.XMLHTTP");
}
}
functionstartRequest(){
createXMLHttpRequest();
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.open("GET","HelloAjaxEx-1.txt");
xmlHttp.send(null);
}
functionhandleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
alert("服务端回应:
"+xmlHttp.responseText);
}
}
}
在startRequest()中会建立XMLHttpRequest,并发出非同步请求取得HelloAjaxEx-1.txt,在当中只是简单的文字信息,注意如果当中要编写中文,则文字文件必须储存为UTF8,假设HelloAjaxEx1-1.txt如下编写:
HelloAjaxEx-1.txt
这是非同步请求的回应文字
您可以按下链结来观看结果。
您可以结合DOM来显示取得的回应文字,不必使用对话方块或重清(Refresh)网页,例如在网页中设定一个
:
HelloAjaxEx-2.html
DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
Hello!Ajax!
Examples...
而HelloAjaxEx-2.js可以改写如下:
HelloAjaxEx-2.js
varxmlHttp;
functioncreateXMLHttpRequest(){
if(window.XMLHttpRequest){
xmlHttp=newXMLHttpRequest();
}
elseif(window.ActiveXObject){
xmlHttp=newActiveXObject("Microsoft.XMLHTTP");
}
}
functionstartRequest(){
createXMLHttpRequest();
xmlHttp.onreadystatechange=handleStateChange;
xmlHttp.open("GET","HelloAjaxEx-2.txt");
xmlHttp.send(null);
}
functionhandleStateChange(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
document.getElementById("response").innerHTML=
xmlHttp.responseText;
}
}
}
在这边为了简化范例,直接使用DOM对象的innerHTML属性,您可以按链结观看结果。
40.4发送请求参数
如果在请求时,要连带发送相关参数,若是使用GET的方式发送参数,则将参数附加在URL上即可,例如:
varurlAndqueryString="yourApp?
name=justin&age=30";
xmlHttp.open("GET",urlAndqueryString);
xmlHttp.send(null);
如果发送请求时使用POST,那么将要发送的资料塞到send()中即可,例如:
varurl="yourApp";
varqueryString="name=justin&age=30";
xmlHttp.open(“POST",url);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttp.send(queryString);
由于塞到POST本体中的资料有可能是表单的name/value,也有可能是XML、JSON等格式,您必须告诉伺服端如何剖析表单本体内容,这可以设定Content-Type的header来告知,以name/value或JSON格式来说,就要设定Content-Type为application/x-www-form-urlencoded,如果是XML文件的话,则要设定text/xml。
以下以简单的实例示范如何以GET及POST发送请求参数,假设您用以下的Servlet来处理请求:
GetPostServlet.java
packageonlyfun.caterpillar;
importjava.io.IOException;
importjava.io.PrintWriter;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassGetPostServletextendsjavax.servlet.http.HttpServletimplements
javax.servlet.Servlet{
publicGetPostServlet(){
super();
}
protectedvoiddoGet(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException{
doResponse(request,response,"GET");
}
protectedvoiddoPost(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,IOException{
doResponse(request,response,"POST");
}
privatevoiddoResponse(HttpServletRequestrequest,
HttpServletResponseresponse,Stringmethod)
throwsServletException,IOException{
Stringname=request.getParameter("name");
response.setContentType("text/html");
PrintWriterout=response.getWriter();
out.println(method+":
Hello!
"+name+"!
");
out.flush();
out.close();
}
}
回应只是简单的传回发送的请求参数值,并加上GET或POST表示接收到何种请求,假设您使用以下的网页来发送请求:
GETPOSTEx-1.html
DOCTYPEhtmlPUBLIC
"-//W3C//DTDHTML4.01Transitional//EN""http:
//www.w3.org/TR/html4/loose.dtd">
GET、POST
网页上分别有GET与POST两个按钮,按下后分别由GETPOSTEx-1.js中的doGetRequest()或doPostRequest()来发送GET、POST请求,假设GETPOSTEx-1.js撰写如下:
由于POST时,网址URL并不会有所变化,在某些浏览器,如果请求的URL是相同的,则会利用快取中的资料,为了避免资料快取,则您可以故意加上一个timeStamp请求参数,附上当时系统的时间,如此每次请求时URL就不会相同。