ajax-XHR对象

前端之家收集整理的这篇文章主要介绍了ajax-XHR对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Ajax,是对Asynchronous Javascript+XML的简写。Ajax技术的核心是XMLHttpRequest对象(XHR)。XHR为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。

一、XHR对象。

IE5是第一款引入XHR对象的浏览器。在IE5中,XHR对象是通过MSXML库中的一个ActiveX对象实现的。因此,在IE中可能会遇到3种不同版本的XHR对象,

即:MSXML2.XMLHttp、

MSXML2.XMLHttp.3.0、

MSXML2.XMLHttp.6.0。

要使用MSXML库中的XHR对象,需要编写一个函数。这个函数会尽力根据IE中可用的MSXML库的情况创建最新版本的XHR对象。例如:

//适用于IE7之前的版本
function createXHR(){
	if(typeof arguments.callee.activeXString != "string"){
		var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"];
		for(var i = 0,len = version.length; i < len; i++){
			try{
				var xhr = new ActiveXObject(versions[i]);
				arguments.callee.activeXString = versions[i];
				return xhr;
			}catch (ex){
				//code
			}
		}
	}
	return new ActiveXObject(arguments.callee.activeXString);
}

IE7、Firefox、Opera、Chrome和Safari都支持原生的XHR对象。在这些浏览器中创建XHR对象要像下面这样使用XMLHttpRequest构造函数

var xhr = new XMLHttpRequest();

但是如果要全部兼容,就可以使用以下代码

function createXHR(){
	if(typeof XMLHttpRequest != "underfined"){ //检测原生XHR对象是否存在
		return new XMLHttpRequest();
	}else if(typeof ActiveXObject != "underfined"){  //检测ActiveX对象是否存在
		if(typeof arguments.callee.activeXString != "string"){
			var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp"];
			for(var i = 0,len = version.length; i < len; i++){
				try{
					var xhr = new ActiveXObject(versions[i]);
					arguments.callee.activeXString = versions[i];
					return xhr;
				}catch (ex){
					//code
				}
			}
		}
		return new ActiveXObject(arguments.callee.activeXString);
	}else{
		throw new Error("No XHR object available.");
	}
}
这个函数中新增的代码首先检测原生 XHR对象是否存在,如果存在则返回它的新实例。如果原生对象不存在,则检测Active对象。如果这两种对象都不存在,就抛出一个错误。写完这个函数,我们就可以使用下面的代码在所有浏览器中创建XHR对象了。

var xhr = new createXHR();

二、XHR的用法

1、调用第一个方法open()。它接受三个参数:要发送的请求的类型("get"、“post”等)、请求的URL和表示是否异步发送请求的布尔值。如

xhr.open("get","example.PHP",false);
2、发送特定的请求,必须像下面这样调用 send()方法。send()方法接受一个参数,即要作为请求主体发送的数据。如果不需要通过主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必需的。
xhr.send(null);
3、等到服务器响应之后。响应的数据会自动填充 XHR对象的属性,相关的属性简介如下。

responseText:响应主体被返回的文本。

responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的XML DOM文档。

status:响应的HTTP状态。

statusText:HTTP状态的说明。

为确保接收到适当的响应,应该像下面这样检查上述这两种状态代码。第一步检查status属性,以确定响应已经成功返回。一般来说,可以将HTTP状态代码为200作为成功的标志。

if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
	alert(xhr.statusText);
}else{
	alert("Request was unsuccessful:" + xhr.status);
}

4、检测readyState属性。以上步骤是发送同步请求的方法,但多数情况下,我们还是要发送异步请求,才能让javascript继续执行而不必等待响应。此时,可以检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段。这个属性可取的值如下:

0:未初始化。尚未调用open()方法

1:启动。已经调用open()方法,但尚未调用send()方法

2:发送。已经调用send()方法,但尚未接收到响应

3:接收。已经接收到部分响应数据。

4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。

只要readyState属性的值由一个值变成另一个值时,都会触发一次readyStatechange事件。可以利用这个事件来检测每次状态变化后readyState的值。通常,我们只对readyState值为4的阶段感兴趣。因为这时所有数据都已经就绪。不过,必须在调用open()之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性。

var xhr = new createXHR();
xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
			alert(xhr.statusText);
		}else{
			alert("Request was unsuccessful:" + xhr.status);
		}	
	}
};
xhr.open("get",true);
xhr.send(null);
三、HTTP头部信息

每个http请求和响应都会带有相应的头部信息,其中有对开发人员有用,有的也没有什么用。

默认情况下,浏览器在发送XHR请求的同时,还会发送下列头部信息。

Accept:浏览器能够处理的内容类型。

Accept-Charset:浏览器能够显示的字符集。

Accept-Encoding:浏览器能够处理的压缩编码。

Accept-Language:浏览器当前设置的语言。

Connection:浏览器与服务器之间连接的类型。

Cookie:当前页面设置的任何Cookie。

Host:发出请求的页面所在的域。

Referer:发出请求的页面所在的域。

User-Agent:浏览器有用户代理字符串。

1、使用setRequestHeader()方法自定义的请求头部信息。这个方法接受两个参数:头部字段的名称和头部字段的值。而且必须在调用open()方法之后且调用send()方法之前调用。即:

	xhr.open("get","test.txt",true);
	xhr.setRequestHeader("MyHeader","MyValue");
	xhr.send();
2、调用XHR对象的 getResponseHeader()方法并传入头部字段名称,可以取得相应的响应头部信息。而调用 getAllResponseHeaders()方法则可以取得一个包含所有头部信息的长字符串。

	var myHeader = xhr.getResponseHeader("MyHeader");
	var allHerders = xhr.getAllResponseHeaders();

DEMO:

<!DOCTYPE html>
<html>
<head>
<Meta charset="utf-8"/>
<title>ajax demo</title>
<script type="text/javascript">
//XHR对象的构造函数
function createXHR(){
	if(typeof XMLHttpRequest != "underfined"){ //检测原生XHR对象是否存在
		return new XMLHttpRequest();
	}else if(typeof ActiveXObject != "underfined"){  //检测ActiveX对象是否存在
		if(typeof arguments.callee.activeXString != "string"){
			var versions = ["MSXML2.XMLHttp.6.0",len = version.length; i < len; i++){
				try{
					var xhr = new ActiveXObject(versions[i]);
					arguments.callee.activeXString = versions[i];
					return xhr;
				}catch (ex){
					//code
				}
			}
		}
		return new ActiveXObject(arguments.callee.activeXString);
	}else{
		throw new Error("No XHR object available.");
	}
}
//按扭响应函数:创建xhr对象并进行相应操作
function loadXMLDoc(){
	var xhr = new createXHR();
	xhr.onreadystatechange = function(){
		if(xhr.readyState == 4){
			if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
				alert("statusText is "+xhr.statusText);
				alert("responseText is "+xhr.responseText);
				alert("responseXML is "+xhr.responseXML);
				alert("status is "+xhr.status);
			}else{
				alert("Request was unsuccessful:" + xhr.status);
			}	
		}
	};
	xhr.open("get",true);
	xhr.setRequestHeader("Accept","90arther");
	xhr.send();
}

</script>
</head>
<body>

<h2>AJAX</h2>
<button type="button" onclick="loadXMLDoc()">请求数据</button>
<div id="myDiv"></div>
</body>
</html>

、GET请求

GET是最常用的请求类型,最常用于向服务器查询某些信息。对于XHR而言,位于传入open()方法的URL末尾的查询字符串必须经过正确的编码才行。

1、查询字符串中的每个参数的名称和值必须使用encodeURIComponent()进行编码,然后才能放到URL的末尾,而且所有名-值对都必须由和号(&)分隔,如下面的例子所示:

xhr.open("get","example.PHP?name1=value1&name2=value2",true);
2、下面这个函数可以辅助向现有URL的末尾添加查询字符串的参数,这个函数接受三个参数:要添加参数的URL、参数的名称和参数的值。这个函数首先检查URL是否包含问号(以确定是否已经有参数存在)。如果没有,就添加一个问号;否则,就添加一个和号。然后,将参数名称和值进行编码,再添加到URL的末尾。最后返回添加参数之后的URL。
function addURLParam(url,name,value){
	url += (url.indexOf("?")== -1?"?":"&");
	url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
	return url;
}

3、下面是使用这个函数来构建请求URL的示例:

var url = "example.PHP";
url = addURLParam(url,"name","Nicholas");
url = addURLParam(url,"Professional JavaScript");
//初始化请求
xhr.open("get",url,false);
四、POST 请求

POST请求的主体可以包含非常多的数据,而且格式不限。在open()方法第一个参数的位置传入"post",就可以初始化一个POST请求,如下面的例子所示:

xhr.open("post",true);

1、默认情况下,服务器对POST请求和提交表单的请求并不会一视同仁。因此,服务器端必须有程序来读取发送过来的原始数据,并从中解析出有用的部分。不过,我们可以使用XHR来模仿表单提交:首先将Content-Type头部信息设置为application/x-www-form-urlencoded,也就是表单提交时的内容类型,其次是以适当的格式 创建一个字符串。

function submitData(){
	var xhr = createXHR();
	xhr.onreadystatechange = function (event){
		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("post","postexample.PHP",true);
	xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	var form = document.getElementById("user-info");
	xhr.send(serialize(form));
}
2、这个函数可以将ID为"user-info"的表单中的数据序列化之后发送给服务器,而下面的示例PHP文件postexample.PHP就可以通过$_POST取得提交的数据了。
<?PHP 
	header("Content-Type:text/plain");//如果不设置Content-Type头部信息,那么发送给服务器的数据就不会出现在$_POST超级全局变量中。
	echo <<<EOF
	Name:{$_POST['user-name']}
	Email:{$_POST['user-email']}
	EOF;
?>

五、浏览器差异

1、超时设定

IE8为XHR对象添加了一个timeout属性,表示请求在等待响应多少毫秒之后就终止。在给timeout设置一个数值后,如果在规定时间内浏览器还没有收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序。

var xhr = createXHR();
xhr.onreadystatechange = function(event){
	try{
		if(xhr.readyState == 4){
			if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
				alert(xhr.responseText);
			}else{
				alert("Request was unsuccessful:"+ xhr.status);
			}
		}
	}catch (ex){
		//假设由ontimeout事件处理程序处理
	}
};
xhr.open("get","timeout.PHP",true);
xhr.timeout = 1000;
xhr.ontimeout = function(){
	alert("Request did not not return in a second.");
};
xhr.send(null);

2、加载(load)事件

Firefox实现中引入了load事件,用以替代readystatechange事件。响应接收完毕将触发load事件,因此也就没有必要去检查readyState属性了。而onload事件处理程序会接收一个event对象,其target属性就指向xhr对象实例,因而可以访问到XHR对象的所有方法属性。然而,并非所有浏览器都这个事件实现了适当的事件对象。结果,开发人员还是要像下面这样被迫使用XHR对象变量:

var xhr = createXHR();
xhr.onload = function (event){
	if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
		alert(xhr.responseTest);
	}else{
		alert("Request was unsuccessful:"+ xhr.status);
	}
};
xhr.open("get","altevents.PHP",true);
xhr.send(null);

只要浏览器接收到服务器的响应,不管其状态如何,都会触发load事件。而这意味着你必须要检查status属性,才能确定数据是否真的已经可用了。Firefox、Opera、Chrome和Safari都支持load事件。

3、进度(progress)事件

Mozilla为XHR添加了progress事件(直到2008年,还没有其它浏览器实现这个特性)。

onprogress事件处理程序会接收到一个event对象,其target属性是XHR对象,但包含着两个额外的属性:position 和totalSiza。其中,position表示已经接收的字节数,totalSize表示根据content-length响应头部确定的预期字节数。

有了这些我们 就可以制作一个进度指示器了。

var xhr = createXHR();
xhr.onload = function(event){
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
        alert(xhr.responseText);
    }else{
        alert("Request was unsuccessful" + xhr.status);
    }
};
xhr.onprogress = function(event){
    var divStatus = document.getElementById("status");
    divStatus.innerHTML = "Received" + event.position + "of" + event.totalSize + "bytes";
};
xhr.open("get","inc.txt",true);
xhr.send(null);
原文链接:https://www.f2er.com/ajax/166374.html

猜你在找的Ajax相关文章