第二十一章
Ajax与Comet
一、XMLHttpRequest对象
1.XHT的用法
在使用XHR对象时,要调用的第一个方法时open( ),它接受3个参数:要发送的请求的类型、请求的URL和表示是否异步发送请求的布尔值。下面是调用这个方法的例子:
xhr.open( “get” , ”example.php” , false ) ;
这段代码会启动一个针对example.php的GET请求。有两点需要注意:一是URL相对于执行代码的当前页面;二是调用open( )方法并不会真正发送请求,而只是启动一个请求以备发送。
要发送特定的请求,只能像下面这样调用send( )方法 ;
xhr.open( “get” , “example.php” , false) ;
xhr.send( null ) ;
这里的send( )方法接收一个参数,即要作为请求主体发送的数据。如果不需要通过请求主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必须的。调用send( )之后,请求就会被分派到服务器。
XHR对象的readyState属性表示请求/响应过程的当前活动阶段。这个属性可取的值如下:
0:未初始化。已经调用open()方法,但尚未调用send()方法。
1:启动。已经调用open()方法,但尚未调用send()方法。
2:发送。已经调用send()方法,但尚未接收到响应。
3:接收。已经接收到部分响应数据。
4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
2.GET请求
GET是最常见的请求类型,最常用于向服务器查询某些信息。使用GET请求经常发生的一个错误,就是查询字符串的格式有问题。查询字符串中每个参数的名称和值都必须使用encodeURIComponent( )进行编码,然后才能放到URL的末尾;而且所有名-值对都必须由和号&分隔。
3.POST请求
使用POST请求通常是向服务器发送应该保存的数据。POST请求应该吧数据作为请求的主体提交,而GET请求传统上不是这样,POST请求可以包含非常多的数据,而且格式不限。
二、XMLHttpRequest2级
1.FormData
现代WEB应用中频繁使用的一项功能就是表单数据的序列化,XMLHttpRequest2级为此定义了FormData类型。FormData为序列化表单以及创建与表单格式相同的数据提供了便利。
2.超时设定
IE8为XHR对象添加了一个timeout属性,表示请求在等待响应多少毫秒之后就终止。在给timeout设置一个数值之后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序。
3.overrideMimeType( )方法
返回响应的MIME类型决定了XHR对象如何处理它,所以提供一种方法能够重写服务器返回的MIME类型时很有用的。
三、进度事件
1.load事件
响应接收完毕后触发load事件,而onload事件处理程序会接收到一个event对象,其target属性就指向XHR对象实例, 因而可以访问到XHR对象的所有方法和属性。
2.progress事件
progress事件会在浏览器接收新数据期间周期性地触发。而onprogress事件处理程序会接收到一个event对象,其target属性是XHR对象,但包含着三个额外的属性:lengthComputable(一个表示进度信息是否可用的布尔值)、position(表示已经接收的字节数)和totalSize(表示根据Content-Length响应头部确定的预期字节数)。
四、跨源资源共享
1.IE对CORS的实现
微软在IE8中引入了XDR类型,这个对象与XHR相似,但能实现安全可靠的跨域通信。以下是XDR与XHR的一些不同之处:
cookie不会随请求发送,也不会随响应返回。
只能设置请求头部信息中的Content-Type字段。
不能访问响应头部信息。
只支持GET和POST请求。
XDR对象的使用方法和XHR非常类似,也是创建一个XDomainRequest的实例,再调用open()方法,再调用send()方法。但与XHR对象的open()方法不同,XDR对象的open()方法只接受两个参数:请求的类型和URL。
2.其他浏览器对CORS的实现
跨域XHR对象也有一些限制:
不能使用setRequestHeader()设置自定义头部
不能发送和接收cookie
调用getAllResponseHdaders()方法总会返回空字符串
3.Preflighted Requests
CORS通过一种叫做Preflighted Requests的透明服务器验证机制支持开发人员使用自定义的头部、GET或POST之外的方法,以及不同类型的主体内容。在使用下列高级选项来发送请求时,就会向服务器发送一个Preflight请求。
4.带凭据的请求
默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明)。通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据。如果服务器接收带凭据的请求,会用下面的HTTP头部来响应。
5.跨浏览器的CORS
即使浏览器对CORS的支持程度都不一样,但所有浏览器都支持简单的请求,因此有必要实现一个跨浏览器的方案。检测XHR是否支持CORS的最简单方式,就是检查是否存在withCredentials属性。再结合检查XDomainRequest对象是否存在,就可以兼顾所有浏览器了。