《javascript高级程序设计》笔记(二十一)

Ajax与Comet

Ajax能够向服务器请求额外的数据而无需卸载页面。

Ajax技术的核心是XMLHttpRequest对象(简称XHR)。可以使用XHR对象取得新数据,然后通过DOM将新数据插入到页面,Ajax通信与数据格式无关 ,不一定是XML数据。

 

(一)XMLHttpRequest对象

IE 7+  Firefox  Opera  Chorme Safari都支持原生的XHR对象,使用XMLHttpRequest构造函数 var xhr = new XMLHttpRequest();

如果要支持IE的早起版本

        function createXHR(){
            if (typeof XMLHttpRequest != "undefined"){
                return new XMLHttpRequest();
            } else if (typeof ActiveXObject != "undefined"){
                if (typeof arguments.callee.activeXString != "string"){
                    var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
                                    "MSXML2.XMLHttp"],
                        i, len;
            
                    for (i=0,len=versions.length; i < len; i++){
                        try {
                            new ActiveXObject(versions[i]);
                            arguments.callee.activeXString = versions[i];
                            break;
                        } catch (ex){
                            //skip
                        }
                    }
                }
            
                return new ActiveXObject(arguments.callee.activeXString);
            } else {
                throw new Error("No XHR object available.");
            }
        }

 

1.XHR的用法

使用XHR对象时,要调用的第一个方法是open(),接收3个参数: 要发送的请求类型(get、post等)、   请求的URL  和   表示是否异步发送请求的布尔值,如:

xhr.open("get","example.php",false)

URL相当于执行代码的当前页面,调用open()方法不会真正发送请求,只是启动一个请求以备发送。

发送特定请求,要调用send()方法: xhr.send(null)。如果不需要通过请求主体发送数据,必须传入null,调用send()之后,请求会被分派到服务器。

 

XHR对象的属性:

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

responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性将保存包含相应数据的HTTP状态。

status:响应的HTTP状态。

statusText:HTTP状态的说明。

 

一般可以将HTTP状态代码为200作为响应成功的标志。状态代码为304表示请求的资源没有被修改,可以直接使用浏览器缓存的版本。

响应主体的内容保存到responseText属性,对非XML数据,responseXML属性的值为0。

 

readyState属性表示请求/响应过程的当前活动阶段:

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

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

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

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

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

 

只要readyState的值变化,就会触发readystatechange事件,可以用它来检测readyState的值。一般只检测4。必须在调用open()之前制定onreadystatechange事件处理程序。

        xhr.onreadystatechange = function(event){
            //请求/相应过程的当前活动阶段
            if (xhr.readyState == 4){
                //HTTP状态代码
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                    alert(xhr.responseText);
                } else {
                    alert("Request was unsuccessful: " + xhr.status);
                }
            }
        };
        xhr.open("get", "example.txt", true);
        xhr.send(null);

接收到响应之前可以调用abort()方法取消异步请求。

 

2.HTTP头部信息

setRequestHeader()方法可以设置自定义的请求头部信息,接收两个参数:头部字段的名称和头部字段的值。必须在调用open()之后切调用send()之前调用它。

 

3.GET请求

GET是最常见的请求,最常用于向服务器查询信息。必要时可以将查询字符串添加到URL末尾。

查询字符串中每个参数的名称和值都必须使用encodeURIComponent()进行编码,才能放到URL的末尾。而且所有名-值对必须由&分隔。

xhr.open("get","example.php?name1=value1&name2=value2",true );

 

4.POST请求

通常用于向服务器发送应该保存的数据。

第一步:在open()方法第一个参数传入"post"

第二步:向send()方法传入某些数据。

使用XHR模仿表单提交:将Context-Type头部信息设置为application/x-www-form-unlencoded,也就是表单提交时的内容类型,然后以适当的格式创建一个字符串。

(二)XMLHttpRequest 2 级

1.FormData

FormData类型:序列化表单、创建于表单格式相同的数据。

var data = new FormData();
data.append("name", "Nico")

append()方法接收两个参数:键和值。通过向FormData构造函数传入表单元素,可以用表单元素的数据填入键和值。

 

2.超时设定

IE8+中   timeout属性表示请求在等待相应多少毫秒后就终止。如果在规定时间浏览器没有接受相应,就会触发timeout事件,进而调用ontimeout事件处理程序。

        xhr.open("get", "timeout.php", true);
        xhr.timeout = 1000;
        xhr.ontimeout = function(){
            alert("Request did not return in a second.");
        };        
        xhr.send(null);

 

3.overrideMimeType()方法

用于重写XHR相应的MIME类型,因为返回响应的MIME类型决定了XHR对象如何处理它,所以能处重写服务器返回的MIME类型很有用。

Firefox、Safari 4+、Opera 10.5、Chrome

(三)进度事件

定义了与客户端服务器通信有关的事件,最早只针对XHR操作,目前被其他API借鉴。

进度事件:loadstart   progress  error  abort   load   loaded

每个请求都是从触发loadstart事件开始,接下来是一或多个progress事件,然后触发error、abort或load事件的一个,最后触发loaded。

Firefox 3.5+   Safari 4+   Chrome  IE8只支持load 

 

1.load事件

相应接收完毕后触发load事件,其target属性指向XHR对象实例,可以访问到XHR对象的所有方法和属性。只要浏览器接收到服务器相应,都会触发load事件,因此要检测status属性。

 

2.progress事件

在浏览器接收新数据期间周期性触发。onprogress事件处理程序接收一个event对象,其target属性是XHR对象,包含三个额外属性:lengthComputable、position、和totalSize。

lengthComputable:进度信息是否可用的布尔值。

position:已经接收的字节数。

totalSize:根据Content-Length响应头部确定的预期字节数。

必须 在调用open方法之前添加onprogress事件处理程序。

 

(四)跨源资源共享

CORS定义了再必须访问跨源资源时浏览器与服务器应该如何沟通。

CORS的思想是使用自定义的HTTP头部让浏览器与服务器沟通,从而决定请求或响应是否成功。

如果服务器任务请求可以接受,就在Access-Control-Allow-Origin头部回发相同的源信息。

 

1.IE对CORS的实现

XDR对象的使用方法与XHR类似,创建一个XDomainRequest的实例,调用open()方法,再调用send()方法。只接受两个参数:请求的类型和URL。

所有XDR请求都是异步执行,请求返还后触发load事件,数据保存在responseText属性。

 

2.其他浏览器对CORS的实现

Firefox 3.5+ Safari4+ Opera  XMLHttpRequest对象实现对CORS的原生支持。在请求另一个域的资源时用XHR对象并在open()方法传入绝对URL。通过跨域XHR对象可以访问status和statusText属性,还支持同步请求。但有一些限制。

 

3.Preflighted Requests

Preflighted Requests:透明服务器验证机制,用来支持开发人员使用自定义的头部、GET或POST之外的方法和不同类型的主体内容。

Firefox 3.5+  Safari 4+  Chrome   IE10及之前不支持

 

4.带凭据的请求

通过将withCredentials属性设置为true可以指定某个请求应该发送凭据。

Firefox 3.5+  Safari 4+  Chrome   IE10及之前不支持

 

5.跨浏览器的CORS

检测XHR是否支持CORS的最简单方式是检查是否存在withCredentials属性,再结合检测XDomainRequest对象是否存在。

 

(五)其他跨域技术

 

1.图像Ping

动态创建图像,使用它们的onload和onerror事件处理程序确定是否接收了相应。

最常用于跟踪用户点击页面或动态广告曝光次数。缺点:只能发送GET请求,无法访问服务器的相应文本。

 

2.JSONP

被包含在函数调用中的JSON,由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。

 

3.Comet

是一种服务器向页面推送数据的技术,能让信息近乎实时地被推送到页面。

实现方式:长轮询和流。

轮询的优势是所有浏览器都支持,使用XHR对象和setTimeout()就能实现。

 

HTTP流:浏览器向服务器发送一个请求,服务器保持链接打开,周期性地向浏览器发送数据。所有服务器端语言支持打印到输出缓存然后更新。

Firefox   Safari   Opera   Chrome   通过监听readystatechange事件及检测readySatate的值是否为3就能利用XHR对象实现HTTP流。

  

4.服务器发送事件

SSE是围绕只读Comet交换推出的API或者模式。SSE API用于创建到服务器的单向链接,武器通过这个连接可以发生任务数量的数据。服务器相应的MIME类型必须是text/event-stream,而且是料理的javascript API能解析格式输出。

Firefox 6+  Safari 5+  Opera11+ Chrome

先要创建新的EventSource对象,并传送一个入口点。传入的URL要与创建对象的页面同源。

 

5.Web Sockets

 在一个独特的持久链接上提供双工、双向通信。标准的HTTP服务器无法实现Web Sockets,只有支持这种协议的专门服务器才能工作。

使用自定义协议而非HTTP协议的好处是能在客户端和服务器之间发送非常少量的数据。确定是制定协议的时间比javascript API长。

Firefox 6+  Safari 5+  Chrome

 

①Web Sockets API

要创建Web Sockets,先实例一个Web Sockets对象并传入要链接的URL(绝对)。

 

②发送和接收数据

要向浏览器发送数据,使用send()方法并传入任意字符串。Web Sockets只能通过连接发送纯文本数据,对于复杂的数据结构,在通过连接发送前要序列化。服务器向客户端发送数据时Web Sockets对象触发message事件。

 

③额外事件

open    error    close

6.SSE 与 Web Sockets

 是否有自由度建立和维护Web Sockets服务器

需不要要双向通信。

 

(六)安全

为确保通过XHR访问的URL安全,通行的做法是验证发送请求者是否有权访问相应的资源。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。