XMLHttpRequest 对象以及 AJAX 技术

XMLHttpRequest 对象

AJAX技术的核心。

是通过 MSXML 库中的一个 ActiveX 对象实现。

在 IE 中可能会遇到三种不同版本的 XHR 对象: MSXML2.XMLHttp、MSXML2.XMLHttp.3.0 和 MSXML2.XMLHttp.6.0

创建 XHR 对象的方法:

function createXHR() {
if (typeof XMLHttpRequest != "undefined") {
// 首先检测原生 XHR 对象是否存在,如果存在则返回它的新实例。
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
// 如果原生对象不存在,则检测 ActiveX 对象
if (typeof arguments.callee.activeXString != "string") {
var version = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp" ],
i, len;
for (i = 0, len=version.length; i < len; i++) {
try {
new ActiveXObject(version[i]);
arguments.callee.activeXString = version[i];
break;
} catch (ex) {
// 跳过
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
// 如果两种对象都不存在,就抛出错误
throw new Error("No XHR object available.");
}
}

由于其他浏览器中对 XHR 的实现与 IE 最早的实现是兼容的,所以可以在所有的浏览器中以相同方式使用上面创建的 xhr 对象。

XHR 的用法

open()

接受 3 个参数:

  1. 要发送的请求的类型(”get”、”post” 等)
  2. 请求的URL
  3. 表示是否异步发送请求的布尔值

p.s.
1、URL 可以是相对地址(一般推荐),也可以是绝对路径

2、调用 open()方法只是启动一个请求以备发送,并没有真正发送出去

只能向同一个域中使用相同端口和协议的 URL 发送请求。
如果 URL 与启动请求的页面有任何差别,都会引发安全错误。

send()

在使用 open() 方法启动请求之后,可以调用 send() 方法

接受一个参数: 作为请求主体发送的数据(不需要的话则必须传入 null,因为对于部分浏览器来说是该参数是必须的)

服务器响应后,JS 代码继续执行,并且响应的数据会自动填充 XHR 对象的属性。相关属性如下:

  • responseText:作为响应主体被返回的文本
  • responseXML:如果响应的内容是”text/xml”或”application/xml”,这个属性中将保存包含着响应数据的 XML DOM 文档
  • status:响应的 HTTP 状态
  • statusText:HTTP 状态的说明

返回之后,通过检测 status 来决定下一步的操作,而不要依赖 statusText,因为后者在跨浏览器使用时不太可靠。
无论内容类型是什么,响应主体的内容都会保存在 responseText 属性中;而对于非 XML 数据而言,responseXML 属性的值将为 null。

发送异步请求时,通常会检测 XHR 对象的 readyState 属性,这个属性表示请求/响应过程的当前活动阶段。可能值如下:

  • 0: 未初始化。尚未调用 open()方法
  • 1: 启动。已经调用 open()方法,但还没调用 send()方法
  • 2: 发送。已经调用了 send()方法,但尚未接收到响应
  • 3: 接收。已经接收到部分响应数据
  • 4: 完成。已经接收全部响应数据,而且已经可以在客户端中使用了

readystatechange 事件,可以用来检测每次状态变化后 readyState 的值。通常只关注值为 4 的时候。
不过,必须在调用 open()之前指定 onreadystatechange 事件处理程序才能确保跨浏览器兼容性。

var xhr = createXHR();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ( (xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304 ) {
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get", "example.txt", true);
xhr.send(null);

(To be continued…)