Ajax技术
Ajax技术
制作人:全心全意
Ajax介绍
Ajax开发模式与传统开发模式的比较
传统开发模式:在传统的Web应用模式中,页面中用户的每一次操作都将触发一次返回Web服务器的HTTP请求,服务器进行相应的处理(获得数据、运行与不同的系统会话)后,返回一个HTML页面给客户端。其关系结构图如下图所示。
Ajax开发模式:在Ajax应用中,页面中用户的操作将通过Ajax引擎与服务器进行通信,然后将返回结构提交给客户端页面的Ajax引擎,再由Ajax引擎来决定将这些数据插入到页面的指定位置。其关系结构图如下图所示。
Ajax使用的技术
Ajax是XMLHttpRequest对象和JavaScript、XML、CSS、DOM等多种技术的组合。其中,只有XMLHttpRequest对象是新技术,其他的均为已有技术。Ajax最核心的技术就是XMLHttpRequest,它是一个具有应用程序接口的JavaScript对象,能够使用超文本传输协议(HTTP)连接一个服务器,是微软公司为了满足开发者的需求,于1999年在IE5.0浏览器中率先推出的。现在许多的浏览器都对其提供了支持,不过实现方式与IE有所不同。在Ajax应用中,通过JavaScript操作DOM,可以达到不刷新页面的情况下实时修改用户界面的目的。
XMLHttpRequest对象的使用
通过XMLHttpRequest对象,Ajax可以像桌面应用程序一样只同服务器进行数据层面的交换,而不用每次都刷新页面,也不用每次都将数据处理的工作交给服务器来完成,这样既减轻了服务器的负担,又加快了响应速度,缩短了用户等待的时间。
初始化XMLHttpRequest对象
由于XMLHttpRequest不是一个W3C标准,所以针对不同的浏览器,初始化方法也是不同的。通常情况下,初始化XMLHttpRequest对象只需要考虑两种情况,一种是IE浏览器,另一种是非IE浏览器。
(1)IE浏览器(将XMLHttpRequest实例化为一个ActiveX对象)
var http_request = new ActiveXObject("Msxml2.XMLHTTP");
或者
var http_request = new ActiveXObject("Microsoft.XMLHTTP");
在上面的语法中,Msxml2.XMLHTTP和Microsoft.XMLHTTP是针对IE浏览器的不同版本而进行设置的,目前比较常用的是这两种。
(2)非IE浏览器(将XMLHttpRequest实例化为一个本地JavaScript对象)
var http_request = new XMLHttpRequest();
使用示例:为提高兼容性,可以创建一个跨浏览器的XMLHttpRequest对象。
<script type="text/javascript"> function myname() { var http_request = false; if (window.XMLHttpRequest) { //非IE浏览器 http_request = new XMLHttpRequest(); } else if (window.ActiveXObject) { //IE浏览器 try { http_request = new ActiveXObject("Msxml2.XMLHTTP"); //使用第一种方式初始化 } catch (e) {//第一种方式错误,使用第二种方式初始化 try { } catch (e) { http_request = new ActiveXObject("Microsoft.XMLHTTP"); } } } } </script>
XMLHttpRequest对象的常用方法
XMLHttpRequest对象提供了一些常用方法,通常这些方法可以对请求进行操作。
- open()方法
open()方法用于设置进行异步请求目标的URL、请求方法以及其他参数信息。其语法格式如下:
open("method","URL"[,asyncFlag[,"userName"[,"password"]]])
参数说明:
method:用于指定请求的类型,一般为GET或POST。
URL:用于指定请求地址,可以使用绝对地址或者相对地址,并且可以传递查询字符串。
asyncFlag:为可选参数,用于指定请求方式,异步请求为true,同步请求为false,默认情况下为true。
userName:为可选参数,用于指定请求用户名,没有时可省略。
password:为可选参数,用于指定请求密码,没有时可省略。
- send()方法
send()方法用于向服务器发送请求。如果请求声明为异步,该方法立即返回,否则将等到接收到响应为止。其语法格式如下:
send(content)
参数说明:
content:用于指定发送的数据,可以是DOM对象的实例、输入流或字符串。如果没有参数需要传递,可以设置为null。
- setRequestHeader()方法
setRequestHeader()方法用于为请求的HTTP头设置值。其语法格式如下:
setRequestHeader("header","value")
参数说明:
header:用于指定HTTP头。
value:用于为指定的HTTP头设置值。
注意:该方法必须在调用open()方法之后才能调用。
- abort()方法
abort()方法用于停止或放弃当前异步请求。其语法格式如下:
abort()
- getResponseHeader()方法
getResponseHeader()方法用于以字符串形式返回指定的HTTP头信息。其语法格式如下:
getResponseHeader("headerLabel")
参数说明:
headerLabel:用于指定HTTP头,包括Server、Content-Type和Date等。
- getAllResponseHeaders()方法
getAllResponseHeaders()方法用于以字符串形式返回完整的HTTP头信息,其中包括Server、Date、Content-Type和Content-Length。其语法格式如下:
getAllResponseHeader()
XMLHttpRequest对象的常用属性
XMLHttpRequest对象提供了一些常用属性,通过这些属性可以获取服务器的响应状态及响应内容。
- onreadystatechange属性
onreadystatechange属性用于指定状态改变时所触发的事件处理器。在Ajax中,每个状态改变时都会触发这个事件处理器,通常会调用一个JavaScript函数。
- readyState属性
readyState属性用于获取请求的状态。该属性共包括5个属性值,如下表所示:
值 | 意 义 | 值 | 意 义 |
0 | 未初始化 | 3 | 交互中 |
1 | 正在加载 | 4 | 完成 |
2 | 已加载 |
- responseText属性
responseText属性用于获取服务器的响应,表示为字符串。
- responseXML属性
responseXML属性用于获取服务器的响应,表示为XML。这个对象可以解析为一个DOM对象。
- status属性
status属性用于返回服务器的HTTP状态码,常见的状态码如下所示:
200:成功
202:请求被接受,但未成功
400:错误的请求
404:文件未找到
500:内部服务器错误
- statusText属性
statusText属性用于返回HTTP状态码对应的文本,如OK或Not Fount(未找到)等。
发送请求与处理响应
发送请求
Ajax可以通过XMLHttpRequest对象实现采用异步方式在后台发送请求。通常情况下,Ajax发送请求方式有两种,一种时发送GET请求,另一种是发送POST请求。但是无论发送哪种请求,都需要经过以下4个步骤:
(1)初始化XMLHttpRequest对象。
(2)指定返回结果处理函数(回调函数),用于对返回结果进行处理。
(3)创建与服务器的连接,指定发送请求的方式,以及是否采用异步方式发送请求。
(4)向服务器发送请求。
处理响应
当向服务器发送请求后,接下来就需要处理服务器响应。在向服务器发送请求时,需要通过XMLHttpRequest对象的onreadystatechange属性指定一个回调函数,用于处理服务器响应。在这个回调函数中,首先需要判断服务器的请求状态,保证请求已完成;然后再根据服务器的HTTP状态码,判断服务器对请求的响应是否成功,如果成功,则获取服务器的响应反馈给客户端。
XMLHttpRequest对象提供了两个用来访问服务器响应的属性,一个是responseText属性,返回字符串响应;另一个是responseXML属性,返回XML响应。
返回字符串响应的示例参考《发送请求与处理响应的应用实例》
返回XML响应的示例:
abc.xml文件:
<?xml version="1.0" encoding="utf-8"?> <musics> <music> <name>李玉刚</name> <title>新贵妃醉酒</title> </music> <music> <name>羽泉</name> <title>奔跑</title> </music> </musics>
index.jsp页面:显示格式化后的XML文件信息
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>根据是否登录显示不同的内容</title> </head> <script language="javascript"> function createRequest(url) {//初始化XMLHttpRequest对象 http_request = false; if (window.XMLHttpRequest) { // 非IE浏览器 http_request = new XMLHttpRequest(); //创建XMLHttpRequest对象 } else if (window.ActiveXObject) { // 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对象实例!"); return false; } http_request.onreadystatechange = getResult; //指定返回结果处理函数(回调函数),用于对返回结果进行处理 http_request.open('GET', url, true); //创建与服务器的连接,指定发送请求的方式,以及是否采用异步方式发送请求 http_request.send(null); //向服务器发送请求 } 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("music").length; i++) { var music = xmldoc.getElementsByTagName("music")[i]; str = str + "《" + music.getElementsByTagName("title")[0].firstChild.data + "》由“" + music.getElementsByTagName("name")[0].firstChild.data + "”演唱<br>"; } document.getElementById("music").innerHTML = str; } else { // 请求页面有错误 alert("您所请求的页面有错误!"); } } } function checkUser() { createRequest('abc.xml'); } </script> <body> <b onclick="checkUser()">请求</b> <div id="music"></div> </body> </html>
发送请求与处理响应的应用实例(检测用户名是否唯一)
index.jsp页面:添加收集用户信息的表单元素,调用检测用户名是否唯一的方法
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>检测用户名是否唯一</title> <script language="javascript"> function createRequest(url) {//初始化XMLHttpRequest对象 http_request = false; if (window.XMLHttpRequest) { // 非IE浏览器 http_request = new XMLHttpRequest(); //创建XMLHttpRequest对象 } else if (window.ActiveXObject) { // 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对象实例!"); return false; } http_request.onreadystatechange = getResult; //指定返回结果处理函数(回调函数),用于对返回结果进行处理 http_request.open('GET', url, true); //创建与服务器的连接,指定发送请求的方式,以及是否采用异步方式发送请求 http_request.send(null); //向服务器发送请求 } function getResult() { if (http_request.readyState == 4) { // 判断请求状态 if (http_request.status == 200) { // 请求成功,开始处理返回结果 document.getElementById("toolTip").innerHTML = http_request.responseText; //设置提示内容 document.getElementById("toolTip").style.display = "block"; //显示提示框(id为toolTip的div层) } else { // 请求页面有错误 alert("您所请求的页面有错误!"); } } } function checkUser(userName) { if (userName.value == "") { alert("请输入用户名!"); userName.focus(); return; } else { createRequest('checkUser.jsp?user=' + userName.value); } } </script> <!-- 检测用户名是否唯一返回结果的显示位置--> <style type="text/css"> #toolTip { position: absolute; left: 331px; top: 39px; width: 98px; height: 55px; padding-top: 45px; padding-left: 22px; padding-right: 58px; z-index: 1; display: none; color: red; } </style> </head> <body style="margin: 0px;"> <form method="post" action="" name="form1"> <table width="509" height="352" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td height="54"> </td> </tr> <tr> <td height="253" valign="top"> <div style="position: absolute;"> <table width="100%" height="250" border="0" cellpadding="0" cellspacing="0"> <tr> <td width="18%" height="54" align="right" style="color: #8e6723"><b>用户名:</b></td> <td width="49%"><input name="username" type="text" id="username" size="25"></td> <td width="33%" onClick="checkUser(form1.username);">检测用户名</td> </tr> <tr> <td height="51" align="right" style="color: #8e6723"><b>密码:</b></td> <td><input name="pwd1" type="password" id="pwd1" size="25"></td> <td rowspan="2"> <div id="toolTip"></div> </td> </tr> <tr> <td height="56" align="right" style="color: #8e6723"><b>确认密码:</b></td> <td><input name="pwd2" type="password" id="pwd2" size="25"></td> </tr> <tr> <td height="55" align="right" style="color: #8e6723"><b>E-mail:</b></td> <td colspan="2"><input name="email" type="text" id="email" size="45"></td> </tr> <tr> <td> </td> <td colspan="2">注册</td> </tr> </table> </div> </td> </tr> <tr> <td> </td> </tr> </table> </form> </body> </html>
checkUser.jsp页面:判断输入的用户名是否注册,并输出判断结果。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String[] userList = { "全心全意", "zq", "root", "qxqy" }; //创建一个一维数组 String user = new String(request.getParameter("user").getBytes("ISO-8859-1"), "utf-8"); //获取用户名 Arrays.sort(userList); //对数组排序 int result = Arrays.binarySearch(userList, user); //搜索数组 if (result > -1) { out.println("很抱歉,该用户名已经被注册!"); //输出检测结果 } else { out.println("恭喜您,该用户名没有被注册!"); //输出检测结果 } %>
Ajax解决中文乱码问题
Ajax不支持多种字符集,它默认的字符集是UTF-8,所以在应用Ajax技术的程序中应及时进行编码转换,否则对于程序中出现的中文字符将变成乱码。
发送请求时出现中文乱码
(1)当接收使用GET方法提交的数据时,要将编码转换为GBK或UTF-8。
String selProvince = request.getParameter("parProvince"); //获取选择的省份 selProvince = new String(selProvince.getBytes("ISO-8859-1"),"UTF-8");
(2)由于应用POST方法提交数据时,默认的字符编码是UTF-8,所以当接收使用POST方法提交的数据时,要将编码转换为UTF-8。
String username = request.getParameter("user"); //获取用户名 username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
获取服务器的响应结果时出现中文乱码
由于Ajax在接收responseText或responseXML的值时是按照UTF-8的编码格式进行解码的,所以如果服务器端传递的数据不是UTF-8格式,在接收responseText或responseXML的值时,就可能产生乱码。解决办法是保证从服务器端传递的数据采用UTF-8的编码格式。