要使用Ajax,首先得创建XMLHttpRequest对象 :
var request = false; try{ request = new XMLHttpRequest();//Mozilla,Safari,Opera,IE7等 }catch(e){//IE7以前的版本 try{ request = new ActiveXObject("Msxml2.XMLHTTP");//IE较新版本 }catch(e1){ try{ request = new ActiveXObject("Microsoft.XMLHTTP");//IE较老版本 }catch(e3){ request = false; } } }
这样就创建好XMLHttpRequest对象,该对象有几个常用方法和属性需要知道:
open():建立到服务器的新请求
send():向服务器发送请求
readyState:提供当前HTML的就绪状态
status:服务器响应的状态代码
responseTest:服务器返回的请求响应文本
准备好XMLHttpRequest对象后就可以建立到服务的请求 了:
第一步:结合网页数据构造URL
var zipcode = document.getElementById('zipcode').value; var url = "zipDataServlet?zipcode="+escape(zipcode);
注:escape()方法用于转义不能用明文发送的任何字符。比如,空格将被转换成%20,从而能够在URL中传递这些字符。
第二步:建立申请:
request.open("GET",url,true);
注:该方法有五个参数:
request-type:发送请求的类型。典型的值是GET或POST,但也可以发送HEAD请求
url:要连接的URL
asynch:如果希望使用异步连接则为true,否则为false。该参数是可选的,默认为true
username:如果需要身份验证,则可以在此指定用户名。该参数是可选的,没有默认值
password:如果需要身份验证,则可以在此指定口令。该参数是可选的,没有默认值
一旦请求用open()配置好之后,就可以使用send() 方法发送求的内容,send()方法只有一个参数,就是要发送的内容。
但是我们前面通过URL本身已经发送了zipcode的值,所以这里不需要通过send()传送数据了,只要传递null作为该方法的参数即可:
request.send(null);
由于是异步请求,请求发出后JavaScript方法不会等待服务器处理完成,而是代码继续执行,就是说,将退出该方法把控制权返回给原先页面。
当服务器处理请求时,XMLHttpRequest对象的就绪状态发生变化,需要指定该如何响应这些变化。XMLHttpRequest对象的onreadystatechange属性允许指定一个回调函数反向调用web页面中的代码以响应这些变化。
function processZipData(){ createRequest(); var zipcode = document.getElementById('zipcode').value; var url = "zipDataServlet?zipcode="+escape(zipcode); request.open("GET",url,true); request.onreadystatechange = updatePage; request.send(null); }
注:1.该属性在XMLHttpRequest对象对象调用send()方法之前设置
2.updatePage是函数名称,但不能写成updatePage()的形式
编写回调函数,响应XMLHttpRequest对象状态的变化:
此处的响应是一个弹出警告
function updatePage(){ alert('request state is changed!'); }
运行上面的代码,根据浏览器的不同,我们会看到两次、三次甚至四次警告。原因是XMLHttpRequest对象的状态有五种就绪状态:
0:请求还没有发出(在调用open()之前)
1:请求已经建立但还没有发出(在调用send()之前)
2:请求已经发出,正在处理之中(这里通常是从响应到得到内容头部)
3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应
4:响应已完成,可以访问服务器响应并使用它
不同的浏览器对就绪状态的使用不尽一致,存在一定的跨浏览器问题。但是对于Ajax编程,需要直接处理的唯一状态4,它表示服务器响应已经完成,可以安全的使用响应数据了。基于此,回调函数做如下调整:
function updatePage(){ if(request.readySate == 4){ alert('server is done!'); } }
这样在服务器处理完请求后就会看到一条弹出警告了。
以上代码看起来似乎不错,但是还有一个问题——如果服务器响应请求并完成了处理,但是报告了一个错误怎么办?在Web世界中,HTTP状态(status)可以说明请求中可能发生的各种问题,比如:
404错误码表示页面不存在
403或401错误码表示所访问的数据受到保护或者禁止访问
五楼哪种情况,这些错误码都是从完成的响应 中得到的。话句话说,服务器执行了请求(即XMLHttpRequest对象的就绪状态是4)但是没有返回客户机预想的数据。因此除了就绪状态外,还需要检查XMLHttpRequest对象的状态。状态码200表示一切顺利。如果就绪状态是4而且状态码是200,就可以处理服务器返回的数据了,并且这些数据应该是要求的数据(而不是错误或者其他问题的信息)。
所以我们再次修改回调函数:
function updatePage(){ if(request.readyState == 4){ if(request.status ==200){ alert('server is done!'); } } }
最后,处理服务器返回的数据 。返回的数据(文本格式)保存在XMLHttpRequest对象的responseText属性中(如果服务器选择使用XML响应,则也可以使用在responseXML属性获得)。
function updatePage(){ if(request.readyState == 4){ if(request.status ==200){ var response = request.responseText.split(","); document.getElementById('city').value = response[0]; document.getElementById('province').value = response[1]; } } }
注:得到responseText并使用JavaScript的split()函数从逗号分开,得到的数组放在response中,我们在取出响应的值即可。
我们使用JavaScript事件函数触发Ajax的调用:
<input id="zipcode" type="text" name="zipcode" οnblur="processZipData()"/>
当输入框onblur(失去焦点)事件触发时Ajax就开始运行了!
服务器端使用Servlet(当然也可以使用JSP)处理请求:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Map<String,String> datas = new HashMap<String,String>();
datas.put("1","Hefei,Anhui");
datas.put("2","Tangshan,Hebei");
datas.put("3","Shanghai,Shanghai");
String zipcode = request.getParameter("zipcode");
String data = datas.get(zipcode);
if(null == data){
data = "Error,Error";
}
response.getWriter().println(data);
}