在IE5中,XHR对象是通过MSXML库中的ActiveX对象实现的。在IE中可能会遇到三种不同版本的XHR对象,即MSXML2.XMLHttp、MSXML2.XMLHttp.3.0和MXSML.XMLHttp.6.0。
适用于IE7之前的浏览器的代码:
function createXHR() {
if (typeof arguments.callee.activeXString != "string") {
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],
i, len;
for (var i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (e) {
//
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}
IE7之后的版本和其他浏览器都会使用下面的函数来创建:
var xhr = new XMLHttpRequest();
兼容代码:
function createXHR() {
if (typeof XMLHttpRequest != "undefined") {
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
if (typeof arguments.callee.activeXString != "string") {
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],
i, len;
for (var i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (e) {
//
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR Object available.");
}
}
兼容代码的应用:
var xhr = new createXHR();
XHR的用法
在使用XHR对象时,要调用的第一方法时
open()
,它接收三个参数:要发送请求的类型,请求的URL和表示是否异步发送请求的布尔值。
如:
xhr.open("get", "note.txt", false);
open()表示启动一个请求以备发送,send()方法才是真正的发送;
要发送特定的请求,要向下面一样调用
send()
方法:
如:
xhr.open("get", "note.txt", false);
xhr.send(null);
XHR从服务器返回后,发生变化的属性,即保存服务器相应数据的属性为:
responseText
:作为响应主体被返回的文本responseXML
:如果响应类型是”text/xml”和”application/xml”,则保存着响应数据的XML DOM文档status
:响应的HTTP状态statusText
:HTTP状态的说明
一般来说,可以将HTTP状态吗为200作为成功标志,此时responseText属性内容准备就绪,responseXML也应该能够访问。此外状态吗为304表示请求的资源没有被修改,可以直接使用浏览器中缓存的版本。
完整代码如下:
var xhr = new XMLHttpRequest();
xhr.open("get", "note.txt", false);
xhr.send(null);
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
document.write(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
要注意的是:
我们在多数情况下都要发送异步请求的,才能让js继续执行而不必等待响应。
可以检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段。这个属性可取的值如下:
0:未初始化。尚未调用open();
1:启动。已经调用open()但未调用send();
2:发送。已经调用send()但尚未接收到响应;
3:接收。已经接收到部分响应数据;
4:完成。已经接收到全部响应数据,而且可以在客户端中使用;
具体格式如下:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304) {
//......
}
}
};
xhr.open("get", "user.json", true);
xhr.send();
举个例子:
json文件:
[{
"name": "oliver",
"age": 18,
"user": true
}, {
"name": "troy",
"age": 26,
"user": true
}]
dom:
<pre id="pre"></pre>
<button id="btn">insert</button>
js:
var btn = document.getElementById("btn"),
pre = document.getElementById("pre"),
obj = null;
btn.onclick = function() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304) {
console.log(xhr.responseText);
obj = JSON.parse(xhr.responseText);
pre.innerHTML = obj[1].name; //troy
}
}
};
xhr.open("get", "user.json", true);
xhr.send();
};
当点击btn时,pre部分显示获取的json文件中的部分信息。
另外在接收到响应之前还可以调用
abort()
方法来取消异步请求。
如下所示:
xhr.abort();
在终止请求之后,还应该对XHR对象进行解引用操作。由于内存原因,不建议重用XHR对象。
HTTP头部信息
XHR对象提供了操作请求头部和响应头部信息的方法。 在默认情况下,在发送XHR请求同时,还会发送下列头部信息:
Accept: 浏览器能够处理的内容类型
Accept – Charset: 浏览器能够显示的字符集
Accept – Encoding: 浏览器能够处理的压缩编码
Accept – Language: 浏览器当前设置的语言
Connection: 浏览器与服务器之间连接的类型
Cookie: 当前页面设置的任何Cookie
Host: 发送请求的页面所在的域
Referer: 发送请求的页面的URI
User – Agent: 浏览器的用户代理字符串
使用
setRequestHeader()
方法可以设置自定义的请求头部信息。
这个方法接收两个参数: 头部字段名和头部字段值。 要成功发送请求头部信息, 必须在调用open() 方法之后且send() 方法之前调用它。 建议使用自定义的头部名称。如:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304) {
//......
}
}
};
xhr.open("get", "user.json", true);
xhr.setRequestHeader("MyHeader", "MyValue"); //这里定义
xhr.send();
另外,调用XHR对象的getResponseHeader()
方法传入头部字段名称,可以取得相应的响应头部信息。而调用getAllResponseHeaders()
方法则可以取得一个包含所有头部信息的长字符串:
var myHeader = xhr.getResponseHeader("MyHeader");
var allHeaders = xhr.getAllResponseHeaders();
GET请求
用encodeURIComponent()编码后的格式如下:
xhr.open("get", "example.php?name1=value1&name2=value2", true);
下面的函数可以辅助向现有的URL的末尾添加查询字符串参数:
function addURLParam(url, name, value) {
url += (url.indexOf("?") == -1 ? "?" : "&"); //检查URL是否包含问号(以确定是否已经有参数存在),没有就加上问好,否则添加一个和号
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
return url;
}
举个例子:
var url = "example.php";
url = addURLParam(url, "name", "oli");
url = addURLParam(url, "book", "js");
xhr.open("get", url, false);
POST请求
POST请求通常用于向服务器发送应该保存的数据
使用post提交,要设置头部属性Content-type。如果不设置,会出现数据无法解码和获取等问题。