学习了 Brett McLaughlin 的《掌握Ajax系列》(参考http://www.ibm.com/developerworks/cn/web/wa-ajaxintro/),起初对那个服务器端响应感觉有点迷惑。到底服务器端以什么方式将数据返回给回调函数,做了个测试,终于彻悟了。
以一个简单的注册页面为例。
注册页面为register.jsp,如下所示:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'register.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<style type="text/css">
body{
color:yellow;
}
</style>
</head>
<body bgcolor="#000000">
<form action="">
<table align="center" bgcolor="green" width="40%" border="1" borderLightColor="green" borderDarkColor="#FFFFFF">
<tr>
<td colspan="2" align="center"><b>注册表单</b></td>
</tr>
<tr>
<td align="center" width="30%">姓名</td>
<td width="70%">
<input id="name" type="text" value="" onChange="callMyServer();"/>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<label style="color:red;" id="name_msg"></label>
</td>
</tr>
<tr>
<td align="center" width="30%">密码</td>
<td width="70%">
<input id="pwd" type="text" value="" onChange="callMyServer();"/>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<label style="color:red;" id="pwd_msg"></label>
</td>
</tr>
<tr>
<td align="center" width="30%">邮箱</td>
<td width="70%">
<input id="email" type="text" value="" onChange="callMyServer();"/>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<label style="color:red;" id="email_msg"></label>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input id="submit" type="submit" value="提交"/>
<input id="reset" type="reset" value="重置"/>
</td>
</tr>
</table>
</form>
</body>
</html>
注册表单如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/d7cd54da23281fd9c9f2be37751733ed.bmp)
表单有三个需要输出的文本域:用户名、密码、Email。
对应于每个文本域,对应一个消息提示的label标签,id分别为name_msg、pwd_msg、email_msg。
首先,在该页面的<script language="javascript"></script>之间创建XMLHttpRequest对象:
var xmlHttp = false;
try{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
//window.alert("使用 xmlHttp = new ActiveXObject('Msxml2.XMLHTTP'); 创建了一个XMLHttpRequest对象.");
}
catch(e1){
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
//window.alert("使用 xmlHttp = new ActiveXObject('Microsoft.XMLHTTP'); 创建了一个XMLHttpRequest对象.");
}
catch(e2){
xmlHttp = false;
}
}
if(!xmlHttp && typeof(xmlHttp) != 'undefined'){
xmlHttp = new XMLHttpRequest();
//window.alert("使用 xmlHttp = new XMLHttpRequest(); 创建了一个XMLHttpRequest对象.");
}
接下来,就要编写onChange()触发的事件:callMyServer(),如下所示:
var name;
var pwd;
var email;
function callMyServer(){
name = document.getElementById("name").value;
pwd = document.getElementById("pwd").value;
email = document.getElementById("email").value;
if(name === null || name === ""){
document.getElementById("name_msg").innerHTML = "";
return;
}
if(pwd === null || pwd === ""){
document.getElementById("pwd_msg").innerHTML = "";
return;
}
if(email === null || email === ""){
document.getElementById("email_msg").innerHTML = "";
return;
}
var sendUrl = "getRegister.jsp?name="+name+"&pwd="+pwd+"email="+email;
// window.alert("sendUrl = "+sendUrl);
xmlHttp.open("GET",sendUrl,true);
xmlHttp.onreadystatechange = showMessage; /* 回调函数 */
xmlHttp.send(null);
}
function showMessage(){
if(xmlHttp.readyState == 4){
if(xmlHttp.status==200){
var response = xmlHttp.responseText.split("|");
document.getElementById("name_msg").innerHTML = response[0];
document.getElementById("pwd_msg").innerHTML = response[1];
document.getElementById("email_msg").innerHTML = response[2];
}
}
}
到这里,先看一下执行流程:
1、当表单的文本域的内容发生改变的时候,触发了callMyServer()事件;
2、这时,在callMyServer()方法中,获取该文本域的内容:
name = document.getElementById("name").value;
如果name又回到空状态,则
document.getElementById("name_msg").innerHTML = "";
3、当所有的文本域都输入了内容(即不为空),则触发onChange()事件,将数据提取出来,封装到一个sendUrl中,该sendUrl指定了服务器端要进行验证(业务处理)的组件,这里是JSP组件getRegister.jsp;
4、建立与服务器端的请求连接: xmlHttp.open("GET",sendUrl,true);
5、执行回调函数showMessage:xmlHttp.readyState == 4说明数据接收完毕,xmlHttp.status==200说明请求成功响应了,接下来获取到请求服务器响应的文本信息 xmlHttp.responseText,最后在页面上显示具体的信息。
我开始比较迷惑的就是,服务器端处理后,会以怎样的方式来返回响应的文本,以至于在客户端能够明确怎样去接收(提取)这些数据。
服务器端JSP组件getRegister.jsp中处理过程如下所示:
<% // 获取sendUrl传递进来的数据
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
String email = request.getParameter("email");
if(name.equals("shirdrn")){
out.print("非法用户名,请换一个用户名!"); // 其实是使用out.print()输出到页面上的
}
else{
out.print("恭喜你,用户名合法!|密码合法!|Email可以使用!");// 这里,多个验证都合法,返回多个信息,使用“|”隔开,以便在回调函数中通过split()方法处理分隔开,取出数据,最后使用out.print()输出到页面上的
}
%>
所以,在回调函数showMessage()中,使用了:
var response = xmlHttp.responseText.split("|");
这样,响应数据被放到response数组中,将返回响应数据,以“|”为分隔符,每分隔一个,作为数组response的一个元素。接着,就可以从response数组中提取各个字段的信息了,分别在指定的id的label上显示验证信息:
document.getElementById("name_msg").innerHTML = response[0];
document.getElementById("pwd_msg").innerHTML = response[1];
document.getElementById("email_msg").innerHTML = response[2];
比如,验证通过,则页面如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/b5dc4450be3953273f6f6a879af43387.bmp)