XMLHttpRequest对象
|
|
响应数据
responseText:作为响应主体被返回的文本。
responseXML:如果响应的内容类型是就”text/xml”或”application/xml”,这个属性中将保存包含着响应数据的XML DOM文档
status:响应的HTTP状态。
statusText:HTTP状态的说明。
readyState 属性
0:未初始化。尚未调用open()方法
1:启动。已经调用oepn()方法,但尚未调用send()方法。
2:发送。已经调用send()方法,但尚未接收到响应。
3:接收。已经接收到部分响应数据。
4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
是哪吃力程序的作用域问题。如果使用this对象,在有的浏览器中会导致函数执行错误
HTTP头部信息
默认情况下,在发送XHR请求的同时,还会发送下列头部信息。
Accept:浏览器能够处理的内容类型。
Accept-Charset:浏览器能够显小的字符集。
Accept-Encoding:浏览器能够处理的压缩编码。
Accept-Language:浏览器当前设置的语言。
Connection:浏览器与服务器之间连接的类型。
Cookie:当前页面设置的任何Cookie
Host:发出请求的页面所在的域
Referer:发出请求的页面的URI。注意,HTTP规范将这个头部字段拼写错了,而为保证与规范一致,也只能将错就错了(这个英文单词的正确拼法应该是referrer)
User-Agent:浏览器的用户代理字符串。
setRequestHeader()
参数:头部信息的名称和值
getRequestHeader()
参数:头部信息的名称
getAllRequestHeader()
包含所有头部信息的长字符串
GET请求
必须使用encodeURIComponent()编码
POST请求
|
|
XMLHttpRequest2级
FormData
序列化表单以及创建于表单格式相同的数据(用于通过XHR传输)
超时设置
|
|
overrideMimeType()
用于重写XHR相应的MIME类型
进度事件
loadstart:在接收到响应数据的第一个字节时触发
progress:在接收响应期间持续不断地触发。
error:在请求发生错误时触发。
abort:在因为调用abort()方法而终止连接时触发。
load:在接收到完整的响应数据时触发。
loadend:在通信完成或者触发error、abort或load事件后触发
load事件
用以代替readystatechange事件
响应接受完毕后将会触发load事件,因此没有必要去检查readyState
只要浏览器接收到服务器的响应,不管状态如何,都会触发load事件
progress事件
在浏览器接受新数据期间周期性触发
onprogress事件 处理程序会接受一个event对象,其target属性是XHR对象,有额外三个属性:
lengthComputable:表示进度信息是否可用
position:已经接受的字节
totalSize:Content-Length响应头部确定的预期字节数
跨源资源共享
默认情况下,XHR对象只能访问与包含它的页面位于同一域中的资源。
CORS(跨源资源共享)背后的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
GET或POST发送的请求,它没有自定义的头部,主题内容是text/plain。
在发送该请求时,需要给他附加一个额外的Origin头部
Origin:http//www.baidu.com
如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中会发同样的源信息
Access-Control-Allow-Origin:http//www.baidu.com
IE对CORS的实现
IE8中引入XDR(XdomainRequest)类型。
与XHR类似,但能实现安全可靠的跨域通信。
XDR与XHR不同之处
- cookie不会随请求发送,也不会随响应返回。
- 只能设置请求头部信息中的Content-Type字段。
- 不能访问响应头部信息。
- 只支持GET和POST请求。
这些变化使CSRF(Cross-Site Request Forgery,跨站点请求伪造)和XSS(Cross-SiteScnpting,跨站点脚本)的问题得到了缓解。被请求的资源可以根据它认为合适的任意数据(用户代理、来源页面等)。来决定是否设置Allow-origin头部作为请求的一部分,origin头部的值表示请求的来源域,以便远程资源明确地识别XDR请求。
所有XDR请求都是异步执行的,不能用它来创建同步请求。123456789101112var xdr = new XDomainRequest();xdr.onload = function () {alert(xdr.responseText);};//如果失败,会触发error事件,遗憾的是没有其他信息可用xdr.onerror = function () {alert("Error!");};xdr.open("get", "http://www.somewhere-else.com/xdr.php");xdr.send(null);//终止请求xdr.abort();
与XHR一样,XDR对象也支持timeout属性以及ontimeout事件处理程序。
为支持POST请求,XDR对象提供了contentType属性,用于表示发送数据的格式
其他浏览器对CORS的实现
在尝试打开不同来源的资源时,无需额外编写代码就可以触发这个行为。要请求位于另一个域中的资源,使用标准的XHR对象并在open()方法中传入绝对URL即可
与IE不同,通过跨域XHR对象可以访问status和statusText属性。
限制
- 不能使用setRequestHeader()设置自定义头部
- 不能发送和接收cokie
- 调用getAllRespnseHeaders()方法总会返回空字符串
因此,对于本地资源,最好使用相对URLPreflighted Requests
CORS通过一种叫做Prefltghted Requests的透明服务器验证机制支持开发人员使用自定义的头部、GET或POST之外的方法,以及不同类型的主体内容。在使用下列高级选项来发送请求时,就会向服务器发送一个Preflight请求。这种请求使用OPTIONS方法,发送下列头部 - origin:与简单的请求相同。
- Access-Control-Request-Method:请求自身使用的方法。
- Access-ControlRequest-Headers:(可选)自定义的头部信息,多个头部以逗号分隔
POST发送的请求
Origin:http:\www.nczonline.net
Access-Control-RequestMethod:POST
Access-Control-Request-Headers:NCZ
服务器通过在响应中发送如下头部 - Access- Control-Allow-Origin:与简单的请求相同。
- Access- Control-AllowMethods:允许的方法·多个方法以逗号分隔。
- Access- Control-Allow-Headers:允许的头部,多个头部以逗号分隔
- Access- Control-Max-Age:应该将这个Preflight请求缓存多长时间(以秒表小)。
例如:1234Access- Control-Allow-Origin:http://www.nczonline.netAccess- Control-AllowMethods :POST,GETAccess- Control-Allow-Headers:NCZAccess- Control-Max-Age:1728000g
带凭据的请求
默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等)。
如果服务器接受带凭据的请求,会用下面的HTTP头部来响应。
Access-Control-Allow-Credentialg:true
如果发送的是带凭据的请求,但服务器的响应中没有包含这个头部,那么浏览器就不会把响应交给JavaScript(于是,responseText中将是空字符串,status的值为0,而且会调用onerror事件处理程序)。
跨浏览器的CORS
检测XHR是否支持CORS的最简单方式,就是检查是否存在withCredentials属性。再结合检测XDornainRequest对象是否存在·就可以兼顾所有浏览器了。
XMLHttpRequest与XDomainRequest共同属性方法
- abort():用于停止正在进行的清求。
- onerror():用于替代onreadystatechange检测错误
- onload():用于替代onreadystatechange检测成功
- responseText():用于取得响应内容。
- send():比用于发送请求
以上成员都包含在createcoCORSRequest()函数返回的对象中
其他跨域技术
图像Ping
上述第一种跨域请求技术是使用标签。我们知道,一个网页可以从任何网页中加载图像,不用担心跨域不跨域。这也是在线广告跟踪浏览量的主要方式。
图像Ping最常用于跟踪用户点击页面或动态广告光次数。图像Ping有两个主要的缺点
- 只能发送GET请求
- 无法访问服务器的响应文本
因此,图像Ping只能用于浏览器与服务器间的单向通信。JSONP
JSONP跟JSON差不多,只不过是被包含在函数调用中的JSON
callback({“name”:”vincent”})
JSONP是通过动态<script>元素来使用的,使用时可以为src属性指定一个跨域URL这里的<script>元素,与以<img>兀素类似,都有能力不受限制地从其他域加载资源。
因为JSONP是有效的JavaScript代码,所以在请求完成后,即在JSONP响应加载到页面中以后,就会立即执行。123456function handleResponse(response) {alert("You're at IP address " + response.ip + ", which is in " + response.city + ", " + response.region_name);}var script = document.createElement("script");script.src = "http://freegeoip.net/json/?callback=handleResponse";document.body.insertBefore(script, document.body.firstChild);
优点:
- 在于能与直接访问相应文本,支持浏览器与服务器之间双向通信
Comet
Ajax是种从页面向服务器请求数据的技术,而Comet则是一种服务器向页面推送数据的技术。Comet能够让信息近乎实时地被推送到页面上,非常适合处理体育比赛的分数和股票报价。
有两种实现Comet的方式:长轮询和流。短轮询
长轮询
长轮询是传统轮询(也称为短轮询)的一个翻版,页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的新请求。这一过程在页面打开期间一直持续不断。HTTP流
流不同于上述两种轮询,因为它在页面的整个生命周期内只使用一个HTTP连接。具体来说,就是浏览器向服务器发送一个请求·而服务器保持连接打开,然后周期性地向浏览器发送数据。
在Firefox,Opera,Safari和Chrome中,通过侦听readystatechange事件及检测readystate的值是否为3,就可以利用XHR对象实现HTTP流。在上述这些浏览器中,随着不断从服务器接收数据,readystate的值会周期性地变为3。当readystate值变为3时,respongerext属性中就会保存接收到的所有数据。123456789101112131415161718192021222324function createStreamingClient(url, progress, finished) {var xhr = new XMLHttpRequest(),received = 0;xhr.open("get", url, true);xhr.onreadystatechange = function () {var result;if (xhr.readyState == 3) {//只取得最新数据冰糖调整计数器result = xhr.responseText.substring(received);received += result.length;//调用回调函数progress(result);} else if (xhr.readyState == 4) {finished(xhr.responseText);}};xhr.send(null);return xhr;}var client = createStreamingClient("streaming.php", function (data) {alert("Received: " + data);}, function (data) {alert("Done!");});
服务器发送事件
SSE(Server-Sent Events,服务器发送事件)是围绕只读Comet交互推出的API或者模式。SSE API用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的MIME类型必须婧text/event-stream,而且是浏览器中的JavaScript API能解析格式输出。SSE支持短轮询、长轮询和HTTP流,而且能在断开连接时自动确定何时重新连接。
SSE API
|
|
EventSource有一个readyState属性
0:正在链接到服务器
1:打开了连接
2:关闭了连接
EventSource三个事件
- open:在建立连接时触发。
- message:在从服务器接收到新事件时触发。
- error:在无法建立连接时触发
事件
所谓的服务器事件会通过一个持久的HTTP响应发送·这个响应的MIME类型为text/event-stream,响应的格式是纯文本,最简单的情况是每个数据项都带有前缀data
对以上响应而言,事件流中的第一个message事件返回的event.data值为’foo’,第二个message事件返回的event.data值为”bar”,第三个message事件返回的event.data值为”foo\nbar·(注意中间的换行符)。对于多个连续的以data:开头的数据行,将作为多段数据解析,每个值之间以一个换行符分隔。只有在包含data:的数据行后面有空行时,才会触发message事件,因此在服务器上生成事件流时不能忘了多添加这一行。
通过id:前缀可以给特定的事件指定一个关联的ID,这个ID行位于data:行前面或后面皆可:
data:foo
id:1
设置了ID后,Eventsource对象会跟踪上一次触发的事件。如果连接断开,会向服务器发送一个包含名为Last-Event-ID的特殊HTTP头部的请求,以便服务器知道下一次该触发哪个事件。在多次连接的事件流中,这种机制可以确保浏览器以正确的顺序收到连接的数据段。
Web Sockets
在JavaScript中创建了Web Socket之后,会有一个HTTP请求发到浏览器以发起连接。在取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为Web Socket协议。
由于WebSockets使用了自定义的协议,所以URL模式也略有不同。未加密的连接不再是http,而是ws。加密的连接也不是https,而是wss。
Web Sockets API
必须给WebSocket构造函数 传入绝对URL。同源策略对Web Socket不适用。
实例化WebSocket对象后,浏览器就会马上尝试创建链接
readyState属性表示当前状态
- Websocket.OPENING(0):正在建立连接。
- WebSocket.OPEN(1):已经建立连接
- WebSoCket.CLOSING(2)正在关闭连接。
- WebSocket.CLOSE(3)已经关团连接。
关闭连接
|
|
发送和接收数据
|
|
其他事件
Web Socket事件
- open:在成功建立连接时触发。
- error:在发生错误时触发,连接不能持续。
- close:在连接关团时触发
WebSocket不支持DOM2级事件侦听器。