/**
* 转载请注明作者longdick http://longdick.iteye.com
*
*/
试试纯粹的Ajax吧(一)-----Give me a try!
我们已经做了一个简单的Ajax应用,这个应用里服务端向客户端返回了数据,但是客户端并没有向服务端发送数据,代码如下:
function getValue(){ createRequest(); //创建一个新的Request var url="servlet\\AjaxServlet"; //指定服务端的URL地址,在这里是我们的servlet访问地址 request.open("GET",url,true); request.onreadystatechange=updatePage; request.send(null); }
如果需要向服务端传送参数的话该怎么做呢?
我们只需要在url地址这里加上参数就可以,var url="servlet\\AjaxServlet?address=myHome";
然后在服务端取得这个叫address的参数值就可以了。
代码如下:
private int i=0;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String address=request.getParameter("address");
response.getWriter().write(address+String.valueOf(i++));
}
同时传多个参数都可以,但是有一个注意的地方,就是直接在url里传参数有一个参数长度的上限值,不同的浏览器上限值不同,IE大概是2000个字符;所以,如果你要传给服务端的参数如果较长,最好不要使用这种方式。
作为应对这种情况的手段,我们做如下更改:
function getValue(){ createRequest(); //创建一个新的Request var url="servlet\\AjaxServlet"; //指定服务端的URL地址,在这里是我们的servlet访问地址 request.open("POST",url,true); request.onreadystatechange=updatePage; request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(“address=myHome”); }
请求发送方式改为"POST",然后在send方法里加上参数,这样就不会受参数长度的限制了。但是这时候需要设置request的Content-Type为"appliction/x-www-form-urlencoded",通知服务端像接收表单数据一样接收参数。
然后再发送请求。
现在客户端和服务端之间能够相互交流了,呵呵。。。。
等等,这时候我们用的是request的属性responseText来接收服务端的返回值的,还记得吗:
function updatePage(){ if(request.readyState==4){ if(request.status==200){ var v=request.responseText; document.form1.text1.value=v; }else alert("error status:"+request.status); } }
大部分情况下这个属性运作良好。但是,这个属性只能接收一个字符串;如果我们需要服务端返回多个值呢,那要怎么办???
有人说,好办,我在服务端把多个值凑一块去,做成一个字符串,中间用个字符分隔一下,再传给客户端脚本,在客户端split一下。。。。
这种方法的确能解决这个问题,但是,同时它带来了一些麻烦:服务端和客户端要在每个值排列的顺序定义上保持严格一致,否则会拿到错误的数据;而且,增加一个值和减少一个值都比较麻烦。
解决这个麻烦的最好方式其实是使用一个XML数据作为返回值,然后用request的另外一个属性responseXml来接收这个数据,servlet里面可以这样写:
private int i=0;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String address=request.getParameter("address");
response.setHeader("Content-Type", "text/xml");
response.getWriter().write("<Root><Add>"+address+"</Add><Num>"+String.valueOf(i++)+"</Num></Root>");
}
这时候注意response返回的是一个XML结构的数据,而不再是我们以前用的Plain Text了。所以,我们在服务端返回数据之前,先设置一下Content-Type为'text/xml',说明接下来传输的是xml数据。
而在客户端脚本里,我们这时候不再是使用responseText这个属性来接收了,因为从服务器返回的xml数据已经转成一棵树对象,这个树的名字就叫DOM(文档对象模型),存放在responseXml这个属性里;然后,我们可以利用DOM的特性来取得这个XML里面的值。
function updatePage(){ if(request.readyState==4){ if(request.status==200){ var v=request.responseXML; root=v.getElementsByTagName('Root')[0]; add=root.getElementsByTagName('Add')[0].firstChild.nodeValue; num=root.getElementsByTagName('Num')[0].firstChild.nodeValue; document.form1.text1.value=add+num; request=null;//清空request }else alert("error status:"+request.status); } }
以上是遍历DOM节点的一些基本操作,关于DOM的操作,可以查看相应资料。
如上所述,我们用返回xml的方式获得了多个返回数据,发送有多参数的请求的时候也可以发送xml给服务端,但是一般不建议那样做,会造成服务端额外的解析任务。而且通过网络传输Object是不行的,首先会把这个xml对象序列化以后再通过网络传输,带有标签的xml数据比纯粹的name/value pairs多出很多数据,比较臃肿。 所以,request发送请求的时候尽量还是使用 plain text 的参数对,服务端返回多个数据的时候可以选用xml,如果只返回一个数据,那还是用plain text 吧。