1、Ajax简介
随着Web2.0概念的普及,追求更人性化、更美观的页面效果成了网站开发的必须。Ajax正在其中充当着重要角色。由于Ajax是一个客户端技术,所以无论使用哪种服务器技术(如JSP、PHP、ASP.NET等)都可以使用Ajax。相对于传统的Web应用开发,Ajax运用的是更加先进、更加标准化、更加高效的Web开发技术体系。
1.1 Ajax开发模式与传统开发模式的比较
互联网发展初期,多数网站都采用传统的开发模式。随着Web2.0时代的到来,越来越多的网站开始采用Ajax开发模式。下面将对Ajax开发模式与传统开发模式的比较。
传统开发模式:在传统的Web应用模式中,页面中的用户的每一次操作都触发一次返回Web服务器的HTTP请求,服务器进行相应的处理(获取数据、运行与不同的系统会话)后,返回一个HTML页面给客户端。
Ajax开发模式:而在Ajax应用中,页面中用户的操作将通过Ajax引擎与服务器端进行通信,然后将返回结果提交给客户端页面的Ajax引擎,再由Ajax引擎来决定将这些数据插入到页面的指定位置。对于每个用户的行为,在传统的Web应用模式中,将生成一次HTTP请求,而在Ajax应用开发模式中,将变成对Ajax引擎的一次JavaScript调用。在Ajax应用开发模式中通过JavaScript实现在不刷新整个页面的情况下,对部分数据进行更新,从而降低了网络流量,给用户带来更好的体验。
1.2 Ajax使用的技术
Ajax是XMLHttpRequest对象和JavaScript、XML、CSS、DOM等多种技术的组合。其中,只有XMLHttpRequest对象是新技术,其它的均为已有技术。
2、使用XMLHttpRequest对象
通过 XMLHttpRequest 对象,Ajax可以像桌面应用程序一样,只同服务器进行数据层的交换,而不用每次都刷新页面,也不用每次都将数据处理的工作交给服务器来完成。这样既减轻了服务器的负担,又加快了响应速度,缩短了用户等待的时间。
2.1 初始化XMLHttpRequest对象
在使用 XMLHttpRequest 对象发送请求和处理响应之前,首先需要初始化该对象,由于 XMLHttpRequest 不是一个W3C标准,所以对于不同的浏览器,初始化的方法也是不同的。通常情况下,初始化 XMLHttpRequest 对象只需要考虑两种情况,一种是IE浏览器,另一种是非IE浏览器,下面分别进行介绍。
2.1.1 判断是否IE浏览器(包含IE11)
/**
* 判断是否IE浏览器
*/
function isIE()
{
if(!!window.ActiveXObject || "ActiveXObject" in window)
{
return true;
}
else
{
return false;
}
}
函数说明:
(1)IE早些版本时,IE10及以下,window.ActiveXObject 返回一个对象,!window.ActiveXObject则变为false,!!window.ActiveXObject则为true,因为是或||符号后续无需再判断,返回true。
(2)IE11中,window.ActiveXObject返回undefine,!window.ActiveXObject则变成了true,!!window.ActiveXObject则变成了false,进入 "window.ActiveXObject" in window判断,该判断条件在IE11下返回true。
(3)其他非IE浏览器,如chrome,firefox,window.ActiveXObject都是undefine,!!window.ActiveXObject都是返回的false,而 "window.ActiveXObject" in window也是返回false,因此上述判断函数在非IE浏览器中返回的都是false。
2.1.2 IE浏览器
IE浏览器把 XMLHttpRequest 实例化为一个ActiveX对象。具体方法如下:
var http_request = new ActiveXObject("Msxml2.XMLHTTP");
或者:
var http_request = new ActiveXObject("Microsoft.XMLHTTP");
在上面的语法中,Msxml2.XMLHTTP和Microsoft.XMLHTTP是针对IE浏览器的不同版本而进行设置的,目前比较常用的是这两种。
2.1.3 非IE浏览器
非IE浏览器(如:Firefox、Opera、Mozilla、Safari)把 XMLHttpRequest 对象实例化为一个本地JavaScript对象。具体方法如下:
var http_request = new XMLHttpRequest();
示例:为了提高程序的兼容性,创建一个跨浏览器的 XMLHttpRequest 对象。
<script type="text/javascript">
var http_request = null;
if(window.XMLHttpRequest) //非IE浏览器
{
http_request = new XMLHttpRequest(); //创建XMLHttpRequest对象
}
else if(!!window.ActiveXObject || "ActiveXObject" in window) //IE浏览器
{
try
{
http_request = new ActiveXObject("Msxml2.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e)
{
try
{
http_request = new ActiveXObject("Microsoft.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e) {}
}
}
if (http_request)
{
alert("成功创建XMLHttpRequest对象实例!");
}
else
{
alert("不能创建XMLHttpRequest对象实例!");
}
</script>
2.2 XMLHttpRequest对象的常用方法
XMLHttpRequest对象提供了一些常用的方法,通过这些方法可以对请求进行操作。
2.2.1 open()方法
open()方法用于设置进行异步请求目标的URL、请求方法以及其他参数信息。其具体语法如下:
open(method, url, async, username, password)
参数说明:
method:必填参数,用于指定用来发送请求的HTTP方法(GET,POST,PUT,DELETE或HEAD)。按照HTTP规范,该参数要大写。
url:必填参数,用于指定 XMLHttpRequest 对象把请求发送到的服务器相应的URI,可以使用绝对路径或者相对路径,该路径会被自动解析为绝对路径,并且可以传递查询字符串。
async:可选参数,该参数用于指定是否请求是异步的,其默认值为true。如果需要发送一个同步请求,需要把该参数设置为false。
userName、password:可选参数,如果需要服务器验证访问用户的情况,那么可以设置userName以及password这两个参数。
示例:设置异步请求目标为register.jsp页面,请求方法为GET,请求方式为异步。
http_request.open("GET","register.jsp",true);
2.2.2 send()方法
send()方法用于向服务器发送请求。如果请求声明为异步,该方法将立即返回,否则将等到接收到响应为止。调用open()方法后,就可以通过send()方法按照open()方法设定的参数将请求进行发送。当open()方法中async参数为true时,在send()调用后立即返回,否则将会中断直到请求返回。需要注意的是,send()方法必须在readyState属性值为1时,即调用open()方法以后才能调用。在调用send()方法以后到接收到响应信息之前,readyState属性的值将被设为2;一旦接收到响应消息,readyState属性值将会被设为3;直到响应接收完毕,readyState属性的值才会被设为4。
其语法如下:
send(data)
参数说明:
send()方法使用一个可选的参数,该参数可以包含可变类型的数据。用户可以使用它并通过POST方法把数据发送到服务器。另外,可以显示的使用null参数调用send()方法,这与不同参数调用该方法一样。对于大多数其他的数据类型,在调用send()方法之前,应该使用setRequestHeader()方法先设置Content-Type头部。如果send(data)方法中的data参数的类型为DOMString,那么,数据将被编码为UTF-8。如果数据是Document类型,那么将使用由data.xmlEncoding指定的编码串行化该数据。
示例:向服务器发送一个不包含任何参数的请求。
http_request.send(null);
2.2.3 abort()方法
abort()方法用于停止或放弃当前异步请求,并且将XMLHttpRequest对象设置为初始化状态。其语法如下:
abort()
2.2.4 setRequestHeader()方法
setRequestHeader()方法用于为请求的HTTP头设置值。其语法如下:
setRequestHeader(header,value)
参数说明:
header:用于指定HTTP头。
value:用于为指定的HTTP头设置值。
注意:setRequestHeader()方法必须在调用open()方法之后才能调用。
示例:在发送POST请求时,需要设置Content-Type请求头的值为application/x-www-form-urlencoded,这是就可以通过setRequestHeader()方法进行设置。
http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
2.2.5 getResponseHeader()方法
getResponseHeader()方法用于以字符串形式返回指定的HTTP头信息。其语法如下:
getResponseHeader(headerLabel)
参数说明:
headerLabel:用于指定HTTP头,包括Server、Content-Type和Date等。
示例:获取HTTP头Content-Type的值。
http_request.getResponseHeader("Content-Type");
2.2.6 getAllResponseHeaders()方法
getAllResponseHeaders()方法用于以字符串形式返回完整的HTTP头信息,其中包括Server、Date、Content-Type和Content-Length。其语法如下:
getAllResponseHeaders()
示例:使用getAllResponseHeaders()方法获取完整的HTTP头信息。
http_request.getAllResponseHeaders();
2.3 XMLHttpRequest对象的常用属性
XMLHttpRequest 对象提供了一些常用属性,通过这些属性可以获取服务器的响应状态及响应内容。
2.3.1 readyState属性
readyState属性用于获取请求的状态,当一个XMLHttpRequest对象被创建后,readState属性的标识了当前对象正处于什么状态,可以通过对该属性的访问,来判断此次请求的状态然后做出相应的操作。该属性共包括5个属性值,如下表:
值 | 意义 |
---|---|
0 | 未初始化状态:此时,已经创建了一个XMLHttpRequest对象,但是还没有初始化。 |
1 | 准备发送状态:此时,已经调用了XMLHttpRequest对象的open()方法,并且XMLHttpRequest对象已经准备好将一个请求发送到服务器端。 |
2 | 已发送状态:此时,已经通过send()方法把一个请求发送的服务器端,但是还没有收到一个响应。 |
3 | 正在接收状态:此时,已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收到。 |
4 | 完成响应状态:此时,已经完成了HttpResponse响应的接收。 |
2.3.2 responseText属性
responseText属性用于获取服务器的响应,表示为字符串。 responseText属性包含客户端接收到的HTTP响应的文本内容。当readyState属性值为0、1或2时,responseText属性包含一个空字符串;当readyState属性值为3(正在接收)时,响应中包含客户端还未完成的响应信息;当readyState属性值为4(已加载)时,该resoinseText属性才包含完整的响应信息。
2.3.3 responseXML属性
responseXML属性用于获取服务器的响应,表示为XML。这个对象可以解析为一个DOM对象。只有当readyState属性值为4,并且响应头部的Content-Type的MIME类型被指定为XML(text/xml或者application/xml)时,该属性才会值并解析为一个XML文档,否则该属性值为null。如果是回传的XML文档结构不良或者未完成响应回传,该属性值也为null。由此可见,responseXML属性用来描述被XMLHttpRequest解析后的XML文档属性。
2.3.4 status属性
status属性用于返回服务器的HTTP状态码。常用的状态码如下表:
值 | 意义 |
---|---|
200 | 表示成功。 |
202 | 表示请求被接受,但尚未成功。 |
400 | 错误的请求。 |
404 | 文件未找到。 |
500 | 内部服务器错误。 |
注意:仅当readyState属性值为3(正在接收中)或4(已加载)时,才能对此属性进行访问。如果在readyState属性值小于3时,试图存取status属性值,将发生一个异常。
2.3.5 statusText属性
statusText属性用于返回HTTP状态码对应的文本,如OK或者Not Fount(未找到)等。statusText属性描述了HTTP状态代码文本,并且仅当readyState属性值为3或4时才可以用。当readyState属性为其它值时试图存取statusText属性值将引发一个异常。
2.3.6 onreadystatechange属性
onreadystatechange属性用于指定状态改变时所触发的事件处理器。在Ajax中,每当readyState属性值发生改变时,就会触发onreadystatechange事件,通常会调用一个JavaScript函数。
示例:指定状态改变时触发JavaScript函数getResult。
http_request.onreadystatechange = getResult; //调用返回结果处理函数
注意:在指定所触发的事件处理器时,所调用的JavaScript函数不能添加小括号及指定参数名。不过这里可以使用匿名函数。例如,要调用带参数的函数getResult(),可以使用下面的代码:
//通过匿名函数指定要带参数的函数
http_request.onreadystatechange = function()
{
getResult("添加的参数"); //调用带参数的函数
};
3、与服务器通信(发送请求与处理响应)
3.1 发送请求
Ajax可以通过XMLHttpRequest对象实现采用异步方式在后台发送请求。通常情况下,Ajax发送请求有两种,一种是发送GET请求,另一种是发送POST请求。但是无论发送哪种请求,都需要经过以下4个步骤。
(1)初始化XMLHttpRequest对象。为了提高程序的兼容性,需要创建一个跨浏览器的XMLHttpRequest对象,并且判断XMLHttpRequest对象的实例是否成功,如果不成功,则给予提示。
示例:发送请求。
var http_request = null;
if(window.XMLHttpRequest) //非IE浏览器
{
http_request = new XMLHttpRequest(); //创建XMLHttpRequest对象
}
else if(!!window.ActiveXObject || "ActiveXObject" in window) //IE浏览器
{
try
{
http_request = new ActiveXObject("Msxml2.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e)
{
try
{
http_request = new ActiveXObject("Microsoft.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e) {}
}
}
if (http_request)
{
alert("成功创建XMLHttpRequest对象实例!");
}
else
{
alert("不能创建XMLHttpRequest对象实例!");
}
(2)为XMLHttpRequest对象指定一个返回结果处理函数(即回调函数),用于对返回结果进行处理。
示例:设置回调函数。
http_request.onreadystatechange = getResult; //调用返回结果处理函数
注意:在指定所触发的事件处理器时,所调用的JavaScript函数不能添加小括号及指定参数名。不过这里可以使用匿名函数。例如,要调用带参数的函数getResult(),可以使用下面的代码:
//通过匿名函数指定要带参数的函数
http_request.onreadystatechange = function()
{
getResult("添加的参数"); //调用带参数的函数
};
(3)创建一个与服务器的连接。在创建时,需要指定发送请求的方式(即GET或POST),以及设置是否采用异步方式发送请求。
示例:采用异步方式发送GET方式的请求。
http_request.open("GET",url,true);
示例:采用异步方式发送POST方式的请求。
http_request.open("POST",url,true);
说明:以Java Web项目为例,在opne()方法中的url参数,可以是一个JSP页面的URL地址,也可以是Servlet的映射地址。也就是说,请求处理页可以是一个JSP页面,也可以是一个Servlet。
技巧:在指定URL参数时,最好将一个时间戳追加到该URL参数的后面,这样可以防止因浏览器缓存结果而不能实时得到最新的结果。例如,可以指定URL参数为以下代码:
var url = "deal.jsp?nocache="+new Date().getTime();
(4)向服务器发送请求。XMLHttpRequest对象的send()方法可以实现向服务器发送请求,该方法需要传递一个参数,如果发送的是GET请求,可以将该参数设置为null,如果发送的是POST请求,可以通过该参数指定要发送的请求参数。
示例:向服务器发送GET请求。
http_request.send(null); //向服务器发送请求
示例:向服务器发送POST请求。
需要注意的是,在发送POST请求前,需要设置正确的请求头。具体代码如下:
http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //设置请求头
上面的这句代码,需要添加在“http_request.send(param);”语句之前。
设置POST参数并发送服务器请求。
var param = "userName=pan_junbiao&age=30"; //组合参数
http_request.send(param); //向服务器发送请求
3.2 处理服务器响应
当向服务器发送请求后,接下来就需要处理服务器响应了。在向服务器发送请求时,需要通过XMLHttpRequest对象的onreadystatechange属性指定一个回调函数,用于处理服务器响应。在这个回调函数中,首先需要判断服务器的请求状态,保证请求已完成,然后再根据服务器的HTTP状态码,判断服务器对请求的响应是否成功,如果成功,则获取服务器的响应反馈给客户端。
XMLHttpRequest对象提供了两个用来访问服务器响应的属性:一个是responseText属性,返回字符串响应;另一个是responseXML属性,返回XML响应。
3.2.1 处理字符串响应
字符串响应通常应用在响应不是特别复杂的情况下。例如,将响应显示在提示对话框中,或者响应只是显示成功或失败的字符串。
示例: 使用Ajax处理字符串响应。
(1)创建getMsg.jsp页面,该页面返回一段字符串。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
out.println("欢迎访问,pan_junbiao的博客");
out.println("<br/>博客地址:https://blog.csdn.net/pan_junbiao");
%>
(2)创建getText.jsp页面,在Ajax回调函数中处理字符串响应,并将其显示到页面中。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ajax处理字符串响应</title>
</head>
<body>
您好!
<div id="divMsg"></div>
<script type="text/javascript">
//1、初始化XMLHttpRequest对象
var http_request = null;
if(window.XMLHttpRequest) //非IE浏览器
{
http_request = new XMLHttpRequest(); //创建XMLHttpRequest对象
}
else if(!!window.ActiveXObject || "ActiveXObject" in window) //IE浏览器
{
try
{
http_request = new ActiveXObject("Msxml2.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e)
{
try
{
http_request = new ActiveXObject("Microsoft.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e) {}
}
}
//2、指定请求返回结果处理函数
http_request.onreadystatechange = getResult; //调用返回结果处理函数
function getResult()
{
if(http_request.readyState==4) //判断请求状态
{
if(http_request.status==200) //请求成功,开始处理返回结果
{
document.getElementById("divMsg").innerHTML = http_request.responseText; //显示内容
}
else
{
alert("您所请求的页面有错误"); //请求页面有错误
}
}
}
//3、创建一个与服务器的路径
http_request.open("POST","getMsg.jsp",true);
//4、向服务器发送请求
http_request.send();
</script>
</body>
</html>
执行结果:
3.2.2 处理XML响应
如果在服务器端需要生成特别复杂的响应,那么就需要应用XML响应。应用XMLHttpRequest对象的responseXML属性,可以生成一个XML文档,而且当前浏览器已经提供了很好的解析XML文档对象的方法。
示例:使用Ajax处理XML响应。
(1)创建XML目录,并在该目录下创建blogInfo.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<blogs>
<blog>
<title>pan_junbiao的博客</title>
<url>https://blog.csdn.net/pan_junbiao</url>
</blog>
<blog>
<title>Ajax技术</title>
<url>https://blog.csdn.net/pan_junbiao/article/details/88943130</url>
</blog>
<blog>
<title>Java面向对象程序设计</title>
<url>https://blog.csdn.net/pan_junbiao/article/details/5297328</url>
</blog>
</blogs>
(2)创建getXML.jsp页面,在Ajax回调函数中处理XML响应,并将其显示到页面中。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ajax处理XML响应</title>
</head>
<body>
<div id="divMsg"></div>
<script type="text/javascript">
//1、初始化XMLHttpRequest对象
var http_request = null;
if(window.XMLHttpRequest) //非IE浏览器
{
http_request = new XMLHttpRequest(); //创建XMLHttpRequest对象
}
else if(!!window.ActiveXObject || "ActiveXObject" in window) //IE浏览器
{
try
{
http_request = new ActiveXObject("Msxml2.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e)
{
try
{
http_request = new ActiveXObject("Microsoft.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e) {}
}
}
//2、指定请求返回结果处理函数
http_request.onreadystatechange = getResult; //调用返回结果处理函数
function getResult()
{
if(http_request.readyState==4) //判断请求状态
{
if(http_request.status==200) //请求成功,开始处理返回结果
{
var xmldoc = http_request.responseXML;
var str="";
for(i=0; i<xmldoc.getElementsByTagName("blog").length; i++)
{
var bolg = xmldoc.getElementsByTagName("blog").item(i);
str += "《" + bolg.getElementsByTagName("title")[0].firstChild.data + "》";
str += "博客地址:" + bolg.getElementsByTagName("url")[0].firstChild.data;
str += "<p>";
}
document.getElementById("divMsg").innerHTML = str; //显示内容
}
else
{
alert("您所请求的页面有错误"); //请求页面有错误
}
}
}
//3、创建一个与服务器的路径
http_request.open("POST","XML/blogInfo.xml",true);
//4、向服务器发送请求
http_request.send();
</script>
</body>
</html>
执行结果:
3.3 一个完整的实例——检测用户名是否唯一
在介绍了向服务器发送请求与处理服务器响应后,下面将通过一个完整的实例,更好的说明在Ajax中如何与服务器通信。
示例:检测用户名是否唯一。
(1)创建register.jsp页面,在该页面中添加用于收集用户注册信息的表单,并使用Ajax实现检测用户名是否唯一。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户注册——检测用户名是否唯一</title>
</head>
<body>
<div align="center">请输入注册信息
<form name="form1">
<table border="0" align="center">
<tr>
<td>用户姓名:</td>
<td><input type="text" id="name" style="width:250px;" /></td>
</tr>
<tr>
<td>博客地址:</td>
<td><input type="text" id="blog" style="width:250px;"/></td>
</tr>
<!-- 以下是提交、取消按钮 -->
<tr>
<td>
<input type="button" value="提交" onclick="checkUser()" />
</td>
<td>
<input type="reset" value="取消" />
</td>
</tr>
</table>
</form>
<b id="spMsg" style="color:red;"></b>
</div>
<script type="text/javascript">
/**
* 检测用户名
*/
function checkUser()
{
var name = document.getElementById("name").value;
if(!name)
{
alert("请输入用户姓名!");
document.getElementById("name").focus();
return;
}
else
{
//向服务器发送Ajax请求
var url = encodeURI("servlet/CheckUser?name=" + name + "&nocache="+new Date().getTime());
createRequest(url);
}
}
/**
* 向服务器发送Ajax请求
*/
function createRequest(url)
{
//1、初始化XMLHttpRequest对象
var http_request = null;
if(window.XMLHttpRequest) //非IE浏览器
{
http_request = new XMLHttpRequest(); //创建XMLHttpRequest对象
}
else if(!!window.ActiveXObject || "ActiveXObject" in window) //IE浏览器
{
try
{
http_request = new ActiveXObject("Msxml2.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e)
{
try
{
http_request = new ActiveXObject("Microsoft.XMLHTTP"); //创建XMLHttpRequest对象
} catch (e) {}
}
}
//判断XMLHttpRequest对象是否创建成功
if (!http_request)
{
alert("不能创建XMLHttpRequest对象实例!");
return false;
}
//2、指定请求返回结果处理函数
http_request.onreadystatechange = getResult; //调用返回结果处理函数
function getResult()
{
if(http_request.readyState==4) //判断请求状态
{
if(http_request.status==200) //请求成功,开始处理返回结果
{
document.getElementById("spMsg").innerHTML = http_request.responseText; //显示内容
}
else
{
alert("您所请求的页面有错误"); //请求页面有错误
}
}
}
//3、创建一个与服务器的路径
http_request.open("GET",url,true);
//4、向服务器发送请求
http_request.send(null);
}
</script>
</body>
</html>
(2)创建com.pjb.servlet包,并在该包下创建用于检测用户名的Servlet类CheckUser.java文件。
package com.pjb.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 检测用户名Servlet类
*
* @author pan_junbiao
*
*/
@WebServlet(name = "CheckUser", urlPatterns = "/servlet/CheckUser")
public class CheckUser extends HttpServlet
{
private static final long serialVersionUID = 1L;
/**
* 检测用户名是否唯一
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// 创建一维数组
String[] userList = { "panjunbiao", "pan_junbiao", "pan_junbiao的博客" };
// 设置request的编码
request.setCharacterEncoding("UTF-8");
// 获取用户姓名参数
String name = request.getParameter("name");
// 搜索数组
Boolean isExist = false;
for (String item : userList)
{
if (item.equals(name))
{
isExist = true;
break;
}
}
// 设置response的编码
response.setCharacterEncoding("UTF-8");
// 获取PrintWriter对象
PrintWriter out = response.getWriter();
// 判断结果
if (isExist)
{
out.println("很抱歉!用户名【" + name + "】已经被注册!");
} else
{
out.println("恭喜您,该用户名未被注册!");
}
// 释放PrintWriter对象
out.flush();
out.close();
}
}
执行结果:
4、解决中文乱码问题
Ajax不支持多种字符集,它默认的字符集是UTF-8,所以在应用Ajax技术的程序中应及时进行编码转换,否则程序中出现的中文符将变成乱码。一般情况下,以下两种情况可能产生中文乱码。
4.1 发送请求时出现中文乱码
将数据提交到服务器有两种方法,一种是使用GET方法提交;另一种是使用POST方法提交。使用不同的方法提交数据,在服务器端接收参数时解决中文乱码的方法是不同的。具体解决方法如下。
(1)当接收使用GET方法提交的数据时,要将编码转换为GBK或是UTF-8。
示例:将省份名称的编码转换为UTF-8。
String selProvince = request.getParameter("parProvince");
selProvince = new String(selProvince.getBytes("ISO-8859-1"), "UTF-8");
(2)由于应用POST方法提交数据时,默认的字符编码是UTF-8,所以当接收使用POST方法提交的数据时,要将编码转换为UTF-8。
示例:将用户名的编码转换为UTF-8。
String userName = request.getParameter("user");
userName = new String(userName.getBytes("ISO-8859-1"), "UTF-8");
4.2 获取服务器的响应结果时出现中文乱码
由于Ajax在接收responseText或responseXML的值时是按照UTF-8的编码格式进行解码的,所以如果服务器端传递的数据不是UTF-8格式,在接收responseText或responseXML的值时,就可能产生乱码。解决的办法是保证从服务器端传递的数据采用UTF-8的编码格式。
5、Ajax重构
Ajax的实现主要依赖于XMLHttpRequest对象,但是在调用其进行异步数据传输时,由于XMLHttpRequest对象的实例在处理事件完成后就会被销毁,所以如果不对该对象进行封装处理,在下次需要调用它时就要重新构建,而且每次调用都需要写一大段的代码,使用起来很不方便。虽然现在有很多开源的Ajax框架都提供了对XMLHttpRequest对象的封装方案,但是如果应用这些框架,通常需要加载很多额外的资源,这势必会浪费很多服务器资源。不过JavaScript脚本语言支持OO编码风格,通过它可以将Ajax所必需的功能封装在对象中。
5.1 重构Ajax文件
示例:创建一个单独的JS文件,名称为AjaxRequest.js,并且在该文件中编写重构Ajax所需的代码。
var net = new Object(); //定义一个全局变量net
//编写构造函数
net.AjaxRequest = function (url, onload, onerror, method, params, async) {
this.req = null;
this.onload = onload;
this.onerror = (onerror) ? onerror : this.defaultError;
this.loadData(url, method, params, async);
}
//编写用于初始化XMLHttpRequest对象并指定处理函数,最后发送HTTP请求的方法
net.AjaxRequest.prototype.loadData = function (url, method, params, async) {
if (!method) {
method = "GET";
}
if (async == null) {
async = true;
}
//创建XMLHttpRequest对象
if (window.XMLHttpRequest) //非IE浏览器
{
this.req = new XMLHttpRequest();
} else if (!!window.ActiveXObject || "ActiveXObject" in window) //IE浏览器
{
try {
this.req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
this.req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
if (this.req) {
try {
//设置请求返回结果处理函数
var loader = this;
this.req.onreadystatechange = function () {
net.AjaxRequest.onReadyState.call(loader);
}
//建立对服务器的调用
this.req.open(method, url, async);
//如果提交方式为POST
if (method == "POST") {
//设置请求头信息
this.req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
//发送请求
this.req.send(params);
} catch (err) {
this.onerror.call(this);
}
}
}
//重构回调函数
net.AjaxRequest.onReadyState = function () {
//判断请求是否完成
if (this.req.readyState == 4) {
//判断请求是否成功
if (this.req.status == 200) {
this.onload.call(this);
} else {
this.onerror.call(this);
}
}
}
//重构默认的错误处理函数
net.AjaxRequest.prototype.defaultError = function () {
alert("错误数据\n回调状态:" + this.req.readyState + "\n状态:" + this.req.status);
}
5.2 应用Ajax重构实现实时系统时钟
示例:实时系统时钟。
(1)创建clock.jsp页面。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>系统时间</title>
</head>
<body>
<h3>欢迎访问,pan_junbiao的博客</h3>
<div id="clock">系统时间</div>
<script src="JS/AjaxRequest.js"></script>
<script type="text/javascript">
//实例化Ajax对象方法
function getSysTime()
{
var loader = new net.AjaxRequest("servlet/GetSysTime?nocache="+new Date().getTime(),deal,onerror,"GET");
}
//回调函数
function deal()
{
document.getElementById("clock").innerHTML="现在的时间:"+this.req.responseText;
}
//错误处理函数
function onerror()
{
alert("出错了");
}
window.onload = function()
{
//调用获取系统时间方法
getSysTime();
//每个1秒调用一次获取系统时间方法
window.setInterval("getSysTime();",1000);
}
</script>
</body>
</html>
(2)创建com.pjb.servlet包,并在该包下创建用于获取系统时间的Servlet类GetSysTime.java文件。
package com.pjb.servlet;
import java.io.IOException;
import java.text.SimpleDateFormat;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 获取系统时间Servlet类
*
* @author pan_junbiao
*/
@WebServlet(name = "GetSysTime", urlPatterns = "/servlet/GetSysTime")
public class GetSysTime extends HttpServlet
{
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String datestyle = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat format = new SimpleDateFormat(datestyle);
java.util.Date nowtime = new java.util.Date();
String strnowtime = format.format(nowtime);
response.setContentType("text/text");
response.setCharacterEncoding("UTF-8");
response.getWriter().print(strnowtime);
}
}
执行结果: