第21章 Ajax与Comet
- Ajax核心是XMLHttpRequest对象,能够以异步的方式从服务器获取更多信息,意味着用户单击后,可以不必刷新页面也能取得数据
XMLHttpReques对象
- 浏览器兼容
1 | function createXHR(){ |
HXR的用法
- open,接收3个参数:要发送的请求的类型(“get”,“post”)、请求的URL、表示是否异步发送请求的布尔值
- URL相对于执行代码的当前页面
- 调用open()方法并不会真正发送请求
- send接受一个参数:作为请求主体发送的数据,不需要则要传入null。
- 请求是同步的,JavaScript代码会等到服务器响应之后再继续执行。在收到响应后,响应的数据会自动填充xhr对象的属性:
responseText: 作为响应主体被返回的文本。
responseXML: 如果响应的内容类型是”text/xml”或”application/xml”,这个属性中将保存包含着响应数据> 的XML DOM文档。
status: 响应的HTTP状态。
statusText: HTTP状态的说明。
1 | xhr.open("get","example.php",false); //同步请求 |
如果要发送异步请求,可以检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段:
0: 未初始化。尚未调用open()方法
1: 启动。已经调用open()方法但尚未调用send()方法
2:发送。已经调用send()方法但尚未接收到响应。
3:接受。已经接受到部分响应数据。
4:完成。已经接受到全部响应数据,而且可以在客户端使用了。readyState属性的值由一个值变成另一个值,都触发一次readystatechange事件。
- 必须在调用open之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性
1 | var xhr = createXHR(); |
HTTP头部
默认情况下,发送XHR请求的同时,还会发送下列头部信息
Accept:浏览器能够处理的内容类型
Accept-Charset:浏览器能够显示的字符集
Accept-Encoding:浏览器能够处理的压缩编码
Accept-Language:浏览器当前设置语言
Connection:浏览器与服务器之间的链接类型
Cookie:当前页面设置的热河Cookie
Host:发出请求的页面所在的域
Referer:发出请求的页面的URI。(正确拼法是referrer)
User-Agent:浏览器的用户代理字符串setRequestHeader方法设置自定义的请求头部信息。接收两个参数:头部字段名称,头部字段值,
- 要成功发送请求头部信息,必须在调用open方法之后,调用send方法之前调用setRequestHeader
- 调用XHR对象的getRequestHeader方法并传入头部字段名称,可以取得相应头部信息
- 调用getAllResponseHeaders()方法则可以获得一个包含所有头部信息的长字符串。
GET请求
- GET请求最常用语想服务器查询某些信息
- 经常发生的一个错误,就是查询字符串的格式有问题,查询字符串的每个参数的名称和值都必须使用encodeURIComponent()编码,然后才能放到URL末尾
- 下面这个函数可以辅助向现有URL的末尾添加查询字符串参数
1 | function addURLParam(url, name, value){ |
POST请求 ###
- 通常用于向服务器发送应该保存的数据,应该把数据作为请求的主体提交,可以包含非常多的数据,且格式不限。
- 如果需要将页面中的表单数据进行序列化,然后通过XHR放到服务器,则可以使用14章的serialize函数来创建字符串
1 | function submitData(){ |
XMLHttpRequest 2级
FormData
- FormData类型:为序列化表单以及创建与表单格式相同的数据(用于通过XHR传输)提供了便利。
1 | function submitData(){ |
超时设定
- timeout属性,表示请求在等待响应多少毫秒之后就终止。如果在规定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件处理程序。
1 | var xhr = createXHR(); |
overrideMimeType()方法
- overrideMimeType()方法:重写XHR响应的MIME类型
- 必须在send()方法之前调用overrideMimeType(),才能保证重写相应的MIME类型
1 | var xhr = createXHR(); |
进度事件
- loadstrart:在接收到响应数据的第一个字节时触发。
- progress:在接收响应期间持续不断地触发。
- error:在请求发生错误时触发
- abort:在因为调用abort()方法而终止连接时触发。
- load:在接收到完整的响应数据时触发。
- loadend:在通信完成或者触发error、abort或load事件后触发。
load事件
- 用于替代readystatechange事件。onload事件处理程序会接收到一个event对象,其target属性就指向XHR对象实例,因而可以访问到XHR对象的所有方法和属性。
1 | window.onload = function(){ |
progress事件
- 这个事件会在浏览器接收新数据期间周期性地触发。
1 | window.onload = function(){ |
跨资源共享 CORS
- 在发送请求时,需要给它附加一个额外的Origin头部,其中包含请求页面的源信息,以便服务器根据这个头部信息来决定是否给予响应。
- 如果服务器认为这个请求可以接受,就在Access-Control_Allow-Origin头部中发相同的源信息。
IE对CORS的支持
IE8中引入了XDR(XDomainRequest)类型,与XHR类似,但能实现安全可靠的跨域通信。与XHR不同:
1.cookie不会随请求发送,也不会随请求返回
2.只能设置头部信息中的Content-Type
3.不能访问响应头部信息
4.只支持GET和POST请求使用方法,也是创建一个XDomainRequest实例,调用open,调用send,open方法只接受两个参数,请求类型,URL。所有请求都是异步。
其他浏览器对CORS的支持
- Firefox3.5+,Safari4+,Chrome,ios版Safari,Android平台中的WebKit都通过XHR对象实现了对CORS的原生支持。
- 限制:
1.不能使用setRequestHeader()设置自定义头部
2.不能发送和接受cookie
3.调用getAllResponseHeaders()方法总会返回空字符串
Preflighted Reqeusts
- CORS通过一种叫做PreFlighted Requests的透明服务器验证机制支持使用自定义头部、get和post之外的方法以及不同类型的主体内容。
带凭据的请求
- 默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等)。通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据。
- 服务器如果接受带凭据的请求,会响应
Access-Control-Allow-Credentials: true
跨浏览器的CORS
1 | function createCORSRequest(method, url){ |
其他跨域技术
图像ping
- 图像ping最常用于跟踪用户点击页面或动态广告曝光次数。
图像ping有两个主要的缺点:
只能发送get请求
无法访问服务器的响应文本。因此,图像ping只能用于浏览器与服务器的单向通信。
1 | var img = new Image(); |
JSONP
- JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名称一般是在请求中指定的。而数据就是传入回调函数中的JSON数据。
与图像Ping相比优点:
能够直接访问相应文本
支持在浏览器与服务器之间双向通信不足:
是从其他域中家在代码执行,可能会夹带一些恶意代码
要确定JSONP请求是否失败并不容易
Comet
- Comet一种更高级的Ajax技术。Ajax是从页面向服务器请求数据的技术,Comet是服务器向页面推送数据的技术。能够让信息近乎实时的被推送到页面上。
- 实现Comet的方式:长轮询和流
服务器发送数据
- SSE(Server-Sent Events,服务器发送事件)是围绕只读Comet交互推出的API或者模式
Web Socket
- Web Socket的目标是在一个单独的持久连接上提供全双工、双向通信。
- 使用标准的HTTP服务器无法实现Web Socket,只有支持这种协议的专门服务器才能工作。
Web Sockets API
- 表示当前状态的readyState属性:
WebSocket.OPENING(0):正在建立连接
WebSocket.OPEN(1):已建立连接
WebSocket.CLOSING(1):正在关闭连接
WebSocket.CLOSE(3):已关闭
发送和接收数据
- send():只能发送纯文本数据,发杂结构的数据要经过序列化。
其他事件
- open:成功建立连接触发
- error:发生错误触发,连接不能持续
- close:连接关闭触发
安全
- 为确保通过XHR访问的URL安全,通行的做法就是验证发送请求者是否有权限访问相应的资源,有下列几种方式可供选择
要求以SSL连接来访问可以通过XHR请求的资源
要求每一次请求都要附带经过相应算法计算得到的验证码。