XMLHttpRequest 对象是AJAX功能的核心,要开发AJAX程序必须从了解XMLHttpRequest 对象开始。
了解XMLHttpRequest 对象就先从创建XMLHttpRequest 对象开始,在不同的浏览器中创建XMLHttpRequest 对象使用不同的方法:
先看看IE创建XMLHttpRequest 对象的方法(方法1):
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //使用较新版本的 IE 创建 IE 兼容的对象(Msxml2.XMLHTTP)
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用较老版本的 IE 创建 IE 兼容的对象(Microsoft.XMLHTTP)
而 Mozilla、Opera、Safari 和大部分非IE的浏览器都使用下面这种方法(方法2)创建XMLHttpRequest 对象:
var xmlhttp = new XMLHttpRequest();
实际上Internet Explorer 使用了一个名为 XMLHttp 的对象,而不是 XMLHttpRequest 对象,而 Mozilla、Opera、Safari 和 大部分非 Microsoft 浏览器都使用的是后者(下文统称 XMLHttpRequest 对象)。IE7开始也开始使用XMLHttpRequest 对象了。
在创建 XMLHttpRequest 对象的时候如果不同的浏览器使用了不正确的方法浏览器都将会报错,并且无法使用该对象。所以我们需要一种可以兼容不同浏览器的创建XMLHttpRequest 对象的方法:
创建兼容多浏览器的 XMLHttpRequest 对象方法
var xmlhttp = false; //创建一个新变量 request 并赋值 false。使用 false 作为判断条件,它表示还没有创建 XMLHttpRequest 对象。
function CreateXMLHttp(){
try{
xmlhttp = new XMLHttpRequest(); //尝试创建 XMLHttpRequest 对象,除 IE 外的浏览器都支持这个方法。
}
catch (e){
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //使用较新版本的 IE 创建 IE 兼容的对象(Msxml2.XMLHTTP)
}
catch (e){
try{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用较老版本的 IE 创建 IE 兼容的对象(Microsoft.XMLHTTP)。
}
catch (failed){
xmlhttp = false; //如果失败则保证 request 的值仍然为 false。
}
}
}
return xmlhttp;
}
判断是否创建成功就很简单了
if (!xmlhttp){
//创建XMLHttpRequest 对象失败!
}
else{
//创建成功!
}
创建好了XMLHttpRequest 对象我们再来看看这个对象的方法、属性以及最重要的onreadystatechange事件句柄吧。
方法:
open() 说明:初始化 HTTP 请求参数,例如 URL 和 HTTP 方法,但是并不发送请求。
abort() 说明:取消当前响应,关闭连接并且结束任何未决的网络活动。
getAllResponseHeaders() 说明:把 HTTP 响应头部作为未解析的字符串返回。
getResponseHeader() 说明:返回指定的 HTTP 响应头部的值。
send() 说明:发送 HTTP 请求,使用传递给 open() 方法的参数,以及传递给该方法的可选请求体。
setRequestHeader() 说明:向一个打开但未发送的请求设置或添加一个 HTTP 请求。
属性:
readyState 说明:HTTP 请求的状态。
responseText 说明:目前为止为服务器接收到的响应体(不包括头部),或者如果还没有接收到数据的话,就是空字符串。
responseXML 说明:对请求的响应,解析为 XML 并作为 Document 对象返回。
status 说明:由服务器返回的 HTTP 状态代码。
statusText 说明:这个属性用名称而不是数字指定了请求的 HTTP 的状态代码。
onreadystatechange 是每次 readyState 属性改变的时候调用的事件句柄函数。
下面从发送请求并处理请求结果的过程来理解一下XMLHttpRequest 对象吧。
发送请求之前自然就是生成一个XMLHttpRequest 对象,代码上面有了就不多写了。
生成一个XMLHttpRequest 对象
var xmlhttp = CreateXMLHttp();
创建好XMLHttpRequest 对象了,那我们要送请求到哪个网站呢,就选择博客园首页的RSS吧。那怎么设置我要请求的网站地址呢,使用open()方法。
open(method, url, async, username, password)
xmlHttp.open("get","http://www.cnblogs.com",true);
get参数表示用get方法,第二个自然就是目标地址,博客园首页,第三个就是表示是否异步了,我们当然使用true了,目标定好了,怎么发送呢。用send()方法。
send(body),send()方法只有一个参数,表示DOM对象,这个DOM对象需要说明的内容很多,先略过。
写xmlhttp.send(null);
就可以了。好了,发送了,那怎么处理返回的结果呢,这个时候就用到XMLHttpRequest 对象最重要的东西了,那就是onreadystatechange事件句柄。什么意思呢,那就需要说明一下XMLHttpRequest 对象的readyState了,readyState有5种状态,分别用数字的 0 到 4 来表示。
状态 名称 描述
0 Uninitialized 初始化状态。XMLHttpRequest 对象已创建(未调用open()之前)或已被 abort() 方法重置。
1 Open open() 方法已调用,但是 send() 方法未调用。请求还没有被发送。
2 Sent Send() 方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应。
3 Receiving 所有响应头部都已经接收到。响应体开始接收但未完成。
4 Loaded HTTP 响应已经完全接收。
但是需要注意的是,onreadystatechange事件句柄不同的浏览器能处理的状态并不一致,IE和FireFox能处理1到4,而Safari能处理2到4的状态,Opera 能处理3、4两中状态。0的状态基本没什么用,因为创建了XMLHttpRequest 对象后都会马上调用open() 方法,这时候状态就变成1了,当然除非你要判断对象是否已经被 abort() 取消,可是这样的情况依然很少。大部分情况下判断是不是4(已经接受完成)这个状态就够了。
好了,明白了readyState有5种状态了,那处理返回结果就是看状态变更到不同的状态我们做不同的处理就可以了,怎么告诉XMLHttpRequest 对象状态变化时让谁来处理这个变化呢。有两种写法,一种是用匿名方法,另一种是指定方法,其实只是不同的写发,作用都一样,看下代码:
xmlhttp.onReadyStateChange = function (){
//处理状态变化的代码
}
//或者
xmlhttp.onReadyStateChange = getResult;
function getResult(){
///处理状态变化的代码
}
//顺便说一下,句柄的名称比较长,可以这样记忆 on ReadyState Change 表示在读取状态改变时
请求发送了,也指定处理方法了,怎么获取返回的内容呢,有responseText和responseXML两个属性可供使用,responseXML是返回对象,需要再解析,后面再说,这里先用responseText,看看返回什么。
alert(xmlhttp.responseText); //看看是不是返回了首页的HTML代码啊。是你就成功了。
整个过程是:创建XMLHttpRequest 对象 -> 指定发送地址及发送方法 -> 发送请求 -> 指定处理方法并处理返回结果。但是需要注意,我们正常的思路理解是这样的,可是onreadystatechange事件句柄指定处理方法需要在发送之前就指定好,否则无法处理状态变化事件。
所以我们应该按照下面的流程来记忆:创建XMLHttpRequest 对象 -> 指定发送地址及发送方法 -> 指定状态变化处理方法 -> 发送请求,请求发送后状态变化了就会自动调用指定的处理方法。
下面是完整的例子代码:
---------------------------------------------------------------------------------------
(注意点:call.html和data.html文件必须放在同一个目录下面)
call.html:
<html>
<head>
<title>AJAX.html</title>
</head>
<script type="text/javascript">
/*通过异步传输XMLHTTP发送参数到ajaxServlet,返回符合条件的XML文档*/
var xmlhttp = false;
function CreateXMLHttp(){
try{
xmlhttp = new XMLHttpRequest(); //尝试创建 XMLHttpRequest 对象,除 IE 外的浏览器都支持这个方法。
}
catch (e){
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //使用较新版本的 IE 创建 IE 兼容的对象(Msxml2.XMLHTTP)
}
catch (e){
try{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用较老版本的 IE 创建 IE 兼容的对象(Microsoft.XMLHTTP)。
}
catch (failed){
xmlhttp = false; //如果失败则保证 request 的值仍然为 false。
}
}
}
return xmlhttp;
}
function sendRequest(){
var url = "./data.html"; //请求data.html文件
CreateXMLHttp();
if(xmlhttp){
xmlhttp.open("GET",url, true);
xmlhttp.onreadystatechange = getResult;
xmlhttp.send(null);
}
}
/*分析返回的XML文档*/
function getResult(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){ //HTTP 响应已经完全接收 并 返回正确的数据。
alert(xmlhttp.responseText);//见返回的内容弹出来显示
}
}
</script>
<body onLoad="sendRequest()">
<table width="80%" border="0" cellspacing="0" cellpadding="0">
<tr><td id="td"> </td></tr>
</table>
</body>
//
data.html:
<h>test!!!!!</h>
------------------------------------------------------------------------------------------------------
下面是结合servlet的ajax例子:
call.html:
<html>
<head>
<title>AJAX.html</title>
</head>
<script type="text/javascript">
/*通过异步传输XMLHTTP发送参数到ajaxServlet,返回符合条件的XML文档*/
var xmlhttp = false;
function CreateXMLHttp(){
try{
xmlhttp = new XMLHttpRequest(); //尝试创建 XMLHttpRequest 对象,除 IE 外的浏览器都支持这个方法。
}
catch (e){
try{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //使用较新版本的 IE 创建 IE 兼容的对象(Msxml2.XMLHTTP)
}
catch (e){
try{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用较老版本的 IE 创建 IE 兼容的对象(Microsoft.XMLHTTP)。
}
catch (failed){
xmlhttp = false; //如果失败则保证 request 的值仍然为 false。
}
}
}
return xmlhttp;
}
function sendRequest(){
var url = "http://127.0.0.1:8080/ch19_1/ajaxServlet?action=send";
CreateXMLHttp();
if(xmlhttp){
xmlhttp.open("GET",url, true);
xmlhttp.onreadystatechange = getResult;
xmlhttp.send(null);
}
}
/*分析返回的XML文档*/
function getResult(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
var type = xmlhttp.responseXML.getElementsByTagName("type_name");
var str=new Array();
for(var i=0;i< type.length;i++){
str[i]=type[i].firstChild.data;
document.all['td'].innerHTML+=str[i]+"";
}
}
}
</script>
<body onLoad="sendRequest()">
<table width="80%" border="0" cellspacing="0" cellpadding="0">
<tr><td id="td"> </td></tr>
</table>
</body>
servlet类:
package com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
*------------------------------------------------------
* 文件名: ajaxServlet.java
* 创建日期: 2005-10-25
* 原作者: miaohai
* 版权所有: miaohai
* 功能说明: 生成XML文档
*
* 修改记录:N/A
*------------------------------------------------------
*/
public class ajaxServlet extends HttpServlet{
private static final String CONTENT_TYPE="text/xml; charset=gb2312";
public void init() throws ServletException{
}
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
response.setContentType(CONTENT_TYPE);
PrintWriter out=response.getWriter();
String action=request.getParameter("action");
if(("send").equals(action)){
StringBuffer sb=new StringBuffer("<type>");
sb.append("<type_name>AA</type_name>");
sb.append("<type_name>BB</type_name>");
sb.append("<type_name>CC</type_name>");
sb.append("<type_name>DD</type_name>");
sb.append("</type>");
out.write(sb.toString());
out.close();
}
}
}
web.xml配置:
<servlet>
<servlet-name>ajaxServlet</servlet-name>
<servlet-class>com.ajaxServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ajaxServlet</servlet-name>
<url-pattern>/ajaxServlet</url-pattern>
</servlet-mapping>