1. 云栖社区>
  2. PHP教程>
  3. 正文

Ajax与Comet的介绍与区别

作者:用户 来源:互联网 时间:2017-12-01 12:56:29

ajaxcomet区别介绍

Ajax与Comet的介绍与区别 - 摘要: 本文讲的是Ajax与Comet的介绍与区别, Ajax(Asynchronous JavaScript + XML的简写)可以向服务器请求数据而无需卸载(刷新)页面,带来更好的用户体验。Ajax技术的核心是XMLHttpRequest对象(简称XHR)。 一、XMLHttpReque

Ajax(Asynchronous JavaScript + XML的简写)可以向服务器请求数据而无需卸载(刷新)页面,带来更好的用户体验。Ajax技术的核心是XMLHttpRequest对象(简称XHR)。


一、XMLHttpRequest对象
/*兼容IE早期版本*/functioncreateXHR(){
if(typeofXMLHttpRequest!="undefined"){returnnewXMLHttpRequest();
}elseif(typeofActiveXObject!="undefined"){//适用于IE7之前的版本
if(typeofarguments.callee.activeXString!="string"){varversions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],
i,len;for(i=0,len=versions.length;i}catch(ex){//skip
}
}
}returnnewActiveXObject(arguments.callee.activeXString);
}else{//XHR对象和ActiveX对象都不存在,则抛出错误
thrownewError("NoXHRobjectavailable.");
}
}
1. XHR的用法
xhr.open("请求的类型get|post等","请求的URL","是否异步发送请求");

说明:(1)URL相对于执行代码的当前页面(当然也可以使用绝对路径)(2)open()方法并不会真正发送请求,而只是启动一个请求以备发送


xhr.send("请求主体发送的数据");

说明:(1)如果不需要通过请求主体发送数据(比如get请求),则必须传入null,因为这个参数对有些浏览器来说是必需的(2)调用send()之后,请求就会被分派到服务器


补充:xhr.open()方法为“false”,即同步请求,JavaScript代码会等到服务器响应后再继续执行;否则,继续执行后续代码。


在收到服务器响应后,相应的数据会自动填充XHR对象的属性。

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


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


status:响应的HTTP状态


statusText:HTTP状态的说明

//为确保接收到适当的响应200:成功;304:资源未被修改
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.responseText);}

说明:(1)有的浏览器会错误的报告成功状态码为204(2)无论内容类型是什么,响应主体的内容都会保存到responseText属性中;而对于XML数据而言,responseXML同时也将被赋值,否则其值为null


对于异步请求,可以检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段

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


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


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


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


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

readyState属性的值发生变化,都会触发readystatechange事件。可以利用这个事件来检测每次状态变化后readyState的值。不过,必须在调用open()之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性。


varxhr=createXHR();xhr.onreadystatechange=function(event){
//不要使用this,作用域会产生问题,在部分浏览器中会执行失败
if(xhr.readyState==4){
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.responseText);
}else{
console.log("Requestwasunsuccessful:"+xhr.status);
}
}
};xhr.open("get","example.txt",true);xhr.send(null);

在接收到响应数据之前可以调用abort()方法来取消异步请求:


xhr.abort();
xhr=null;//解除引用,释放内存
2. HTTP头部信息

setRequestHeader():设置自定义的请求头信息。必须在调用open()方法之后且调用send()方法之前调用。getResponseHeader() getAllResponseHeaders():可以获取指定(全部)响应头信息。


varxhr=createXHR();
xhr.onreadystatechange=function(){};
xhr.open("get","example.php",true);
xhr.setRequestHeader("MyHeader","MyValue");
xhr.send(null);
3. GET请求

open()方法的URL尾部的查询字符串必须经过正确的编码


functionaddURLParam(url,name,value){
url+=(url.indexOf("?")==-1?"?":"&");
url+=encodeURIComponent(name)+"="+encodeURIComponent(value);returnurl;
}varurl="http://test.com";
url=addURLParam(url,"uid",5);
url=addURLParam(url,"siteid",123);//"http://test.com?uid=5&siteid=123"xhr.open("get",url,true);
xhr.send(null);
4. POST请求

POST请求将数据作为请求的主体


/*序列化表单*/functionserialize(form){
varparts=newArray();varfield=null;for(vari=0,len=form.elements.length;ifield=form.elements[i];switch(field.type){case"select-one":case"select-multiple":for(varj=0,optLen=field.options.length;joptValue=(option.hasAttribute("value")?
option.value:option.text);
}else{
optValue=(option.attributes["value"].specified?
option.value:option.text);
}
parts.push(encodeURIComponent(field.name)+"="+
encodeURIComponent(optValue));
}
}break;caseundefined://fieldset
case"file"://fileinput
case"submit"://submitbutton
case"reset"://resetbutton
case"button"://custombutton
break;case"radio"://radiobutton
case"checkbox"://checkbox
if(!field.checked){break;
}/*fallsthrough*/
default:
parts.push(encodeURIComponent(field.name)+"="+
encodeURIComponent(field.value));
}
}
returnparts.join("&");
}
/*发送请求*/functionsubmitData(){
varxhr=createXHR();
xhr.onreadystatechange=function(event){
if(xhr.readyState==4){if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
alert(xhr.responseText);
}else{
alert("Requestwasunsuccessful:"+xhr.status);
}
}
};
xhr.open("post","postexample.php",true);//表单提交的内容类型
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");varform=document.getElementById("user-info");
//请求主体为数据
xhr.send(serialize(form));
}
二、XMLHttpRequest 2级

XMLHttpRequest 1级只是把已有的XHR对象的实现细节描述了出来。而XMLHttpRequest 2级则进一步发展了XHR。并非所有浏览器都完整地实现了XMLHttpRequest 2级规范,但所有浏览器都实现了它规定的部分内容。


1. FormData
//创建FormData对象vardata=newFormData();data.append("name","ligang");
//用表单元素填充xhr.open("post","postexample.php",true);varform=document.getElementById("user-info");//使用FormData的方便之处在于不必明确地在XHR对象上设置请求头。//xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");xhr.send(newFormData(form));
2. 超时设定

IE8为XHR对象添加了一个timeout属性,表示请求在等待响应多少毫秒后就终止。


xhr.open("get","timeout.php",true);
xhr.timeout=60*1000;
xhr.ontimeout=function(){
alert("Requestdidnotreturninasecond.");
};
xhr.send(null);

对于其他浏览器的兼容做法


xhr.open("get","timeout.php",true);
xhr.onreadystatechange=function(event){
if(xhr.readyState==4){//清除定时器
clearTimeout(timeout);if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.responseText);
}else{
console.log("Requestwasunsuccessful:"+xhr.status);
}
}
};//设置超时时间1分钟vartimeout=setTimeout(function(){
xmlHttpRequest.abort();
xmlHttpRequest=null;
},60*1000);
xmlHttpRequest.send(null);
3. overrideMimeType()方法

重写XHR响应的MIME类型,必须在send()方法之前。


如果,服务器返回的MIME类型是text/plain,但数据中实际包含的是XML。根据MIME类型,responseXML属性中仍然是null。此时,通过overrideMimeType()方法,可以保证把响应当作XML而非纯文本来处理(即,responseXML中被赋值)。


varxhr=createXHR();
xhr.open("get","text.php",true);
xhr.overrideMimeType("text/xml");
xhr.send(null);
三、进度事件

6个进度事件:

loadstart:在接收到响应数据的第一个字节时触发。


progress:在接收响应期间持续不断地触发。


error:在请求发生错误时触发。


abort:在因为调用abort()方法而终止时触发。


load:在接收到完整的响应数据时触发。


loadend:在通信完成或者触发error、abort或load事件后触发。Ajax与Comet的介绍与区别

1. load事件

可以代替readystatechagne事件。其处理程序会接收到一个event对象,其target属性指向XHR对象实例,因而可以访问到XHR对象的所有方法和属性。然而,并非所有浏览器都实现了事件对象。


2. progress事件

其处理程序会接收一个event对象,其target属性指向XHR对象实例,但包含着三个额外的属性

lengthComputable:是一个表示进度信息是否可用的布尔值


position:表示已经接收的字节数


totalSize:根据content-length响应头确定的预期字节数注意:其必须在调用open()方法之前添加

varxhr=createXHR();xhr.onload=function(event){
//event.target存在兼容性问题,所以只能使用xhr
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.responseText);
}else{
console.log("Requestwasunsuccessful:"+xhr.status);
}
};xhr.onprogress=function(event){
vardivStatus=document.getElementById("status");
if(event.lengthComputable){
divStatus.innerHTML="Received"+event.position+"of"+event.totalSize+"bytes";
}
};xhr.open("get","altevents.php",true);xhr.send(null);
四、跨源资源共享

CORS(Cross-Origin Resource Sharing)背后的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。


在发送请求时,给其附加一个额外的Origin头部,其中包含请求页面的源信息(协议、域名和端口),以便服务器根据这个头部信息来决定是否给予响应。


Origin:http://www.test.com

如果服务认为这个请求可以接受,在Access-Control-Allow-Origin头部中回发相同的源信息(如果是公共资源,可以回发”*”)。


Access-Control-Allow-Origin:http://www.test.com

注意:请求和响应都不包含cookie信息。


1. IE中实现CORS:XDR(XDomainRequest),所有的XDR请求都是异步的,不能创建同步请求。其使用方法类似于XHR。
2. 其他浏览器对CORS的实现:通过XMLHttpRequest对象实现对CORS的原生支持。只需给open()方法传入绝对地址。支持同步请求。

跨域XHR对象的安全限制:(1)不能使用setRequestHeader()设置自定义头部。(2)不能发送和接收cookie。(3)调用getAllResponseHeaders()方法总会返回空字符串。


建议:访问本地资源,最好使用相对URL;访问远程资源,使用绝对URL。


3. 跨浏览器的CORS
functioncreateCORSRequest(method,url){
varxhr=newXMLHttpRequest();if("withCredentials"inxhr){//检测XHR是否支持CORS的简单方式,就是检测是否存在withCredentials属性
xhr.open(method,url,true);
}elseif(typeofXDomainRequest!="undefined"){//IEXDR
xhr=newXDomainRequest();
xhr.open(method,url);
}else{
xhr=null;
}returnxhr;
}varrequest=createCORSRequest("get","http://www.somewhere-else.com/xdr.php");if(request){
request.onload=function(){
//dosomethingwithrequest.responseText
};
request.send();
}
五、其他跨域技术

利用DOM中能够执行跨域请求的功能,在不依赖XHR对象的情况下也能发送某种请求,其不需要修改服务器端代码。


1. 图像Ping

标签,可以从任何网页中加载图像,无需关注是否跨域。这也是广告跟踪浏览量的主要方式。图像Ping是与服务器进行简单、单向的跨域通信的一种方式。浏览器得不到任何具体的数据。但通过监听load和error事件,可以知道响应是什么时间接收到的。


varimg=newImage();
img.onload=img.error=function(){
console.log("Done!");
};
img.src="http://www.test.com/getImage?id=1";

缺点:(1)只能发送Get请求(2)无法访问服务器的响应文本


2. JSONP(JSON with padding)

两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面调用的函数。回到函数的名字一般是在请求中指定的。而数据是传入回调函数中的JSON数据。JSONP是通过动态

以上是Ajax与Comet的介绍与区别的全部内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有其他相关内容,欢迎继续使用右上角搜索按钮进行搜索ajax , comet , 区别 介绍 ,以便于您获取更多的相关知识。