js高级程序设计笔记--Ajax与comet

XMLHttpRequest对象

在IE5中,XHR对象是通过MSXML库中的一个ActiveX对象实现的。因此IE中有三种不同版本的XHR对象:MSXML2.XMLHttp,MSXML2.XMLHttp.3.0,MSXML2.XMLHttp.6.0.
IE7+,Firefox,Opera,Chrome,Safari都支持原生的XHR对象。可以使用XMLHttpRequest构造函数。

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

XHR用法

1.调用open()方法,接收3个参数:要发送的请求的类型,请求的URL,表示是否异步发送请求的布尔值。

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

2.调用send()方法,接收1个参数,作为请求主体发送的数据。如果没有也要传入null.
响应的数据会自动填充XHR对象的属性:
responseText:作为响应主体被返回的文本。
responseXML:当响应的内容类型 是“text/xml”或”application/xml”时,被返回。
status:响应的HTTP状态码
statusText;http状态的说明。(200表示成功,304表示请求的资源没被修改,可用浏览器缓存的版本)

发送异步请求时可检测XHR对象的readyState属性。取值如下:

0:未初始化,尚未调用open方法。
1:启动,已经调用open()方法。
2:已经调用send()方法。
3:接收,已经接收到部分响应数据。
4. 完成。已经接收到全部响应数据。

只要readyState属性改变。就会触发readystatechange事件。

var xhr = createXHR();
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if((xhr.status >=200 && xhr.status <300) || xhr.status = 304){
            alert(xhr.responseText);
        }else{
            alert("request was unsuccessful");
        }
    }
}

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

xhr.abort();

setRequestHeader(headerName,headerValue):设置头部信息。
getRequestHeader(headName):取得相应的响应头部信息。
getAllRequestHeaders():取得一个包含所有头部信息的长字符串。

XHR模仿表单提交:

xhr.open("post","post.php",true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var form = document.getElementById("user-info");
xhr.send(serialize(form));

XMLHttpRequest2级

FormData

XMLHttpRequest2级为表单数据的序列化定义了FormData类型。

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

也可以穿入表单元素

var data = new FormData(document.forms[0]);

创建之后可以直接传给XHR的send()方法。

xhr.send(new FormData(form));

使用此类型的方便之处在于不必明确的在XHR对象上设置请求头部。支持FormData的浏览器有FireFox4+,Safari5+,Chrome.

超时设定

IE8为XHR对象添加了一个timeout属性。表示请求在等待响应都少毫秒之后就终止。进而触发ontimeout事件处理程序。这项功能后来被收入了XMLHttpRequest2级规范中。

xhr.timeout = 1000;//仅适用于IE8+
xhr.ontimeout = function(){
    .....
}

overrideMimeType()方法

强制xhr对象将响应当做某种数据类型的格式来处理。

xhr.overrideMimeType("text/xml");
xhr.send(null);

进度事件

6个进度事件:
loadstart:在接收到响应数据的第一个字节时触发。
progress:在接收响应期间持续不断的触发。
error:在请求发生错误时触发。
abort():调用abort()方法终止连接时触发。
load:在接收到完整的相应数据时触发。
loadend:在通信完成或者触发error,abort,load事件后触发。(暂时没有浏览器支持)
IE8+只支持load事件。

load事件

Firefox引入load事件,用以替代readystatechange事件。响应接收完毕后将触发load事件。onload事件接收一个event对象,其target属性指向XHR对象实例。但是并非所有浏览器都实现了这个事件对象。因此还是得像原来那样使用XHR对象变量。

progress事件

Mozilla对XHR的另一个革新是添加了progress事件。onprogress事件处理程序接收一个event对象,该对象包含着三个额外的属性:
lengthComputable:进度信息是否可用的布尔值
position:已经接收的自己数
totalSize:根据Content-Length响应头部确定的预期字节数。

xhr.onprogress = function(event){
    var divStatus = document.getElementById("status");
    if(event.lengthComputable){
        divStatus.innerHTML = "received" + event.position +"of "+event.totalSize+"bytes";
    }
}

跨源资源共享

CORS(Cross-Origin Resource Sharing):定义了在必须访问跨资源时,浏览器与服务器应该如何沟通。使用自定义的Http头部让浏览器与服务器进行沟通,,从而决定请求或响应成功或失败。比如在发送该请求时附加一个额外的Origin头部。

Origin:http://www.nczongline.net

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

Access-Control-Allow-Origin:http://www.nczongline.net

如果没有这个头部或者原信息不匹配,浏览器会驳回请求。注意,请求和响应都包含cookie信息。

IE对CORS的实现

微软在IE8中引入了XDR类型。能够实现安全可靠的跨域通信。XDR与XHR的一些不同之处。

  1. cookie不会随请求发送,也不会随响应返回。
  2. 只能设置请求头部信息中的Content-Type字段。
  3. 不能访问响应头部信息
  4. 只支持get和post请求。

XDR对象的使用方法与XHR对象类似。不同的是open()方法只接受两个参数:请求类型和URl.所有XDR请求都是异步执行的。请求返回后会触发load事件。响应的数据也会保存在responseText属性中。

var xdr = new XDomainRequest();
xdr.onload = function(){
    alert(xdr.responseText);
}
xdr.open("get","http://www.haha.com");
xdr.send(null);

xdr.abort():终止请求。与XHR一样,XDR一样,XDR对象也支持timeout属性以及ontimeout事件处理程序。
为支持post请求,XDR对象提供了contentType属性

xdr.open("post","http://www.hihi.com");
xdr.contentType = "application/x-wwww-form-urlencoded";
xdr.send("name=value1&name2=value2");

其它浏览器对CORS的实现

通过XMLHttpRequest对象实现了CORS的原生支持。要请求另一个域中的资源,使用标准的XHR对象并在open()方法中传入绝对URL即可。
但是跨域XHR对象也有一些限制。
1, 不能使用setRequestHeader()设置自定义头部。
2. 不能发送和接收cookie.

跨浏览器的CORS

function createCORSRequest(method,url){
    var xhr = new XMLHttpRequest();
    if("withCredentials" in xhr){
        xhr.open(method,url,true);
    }else if(typeof XDomainRequest != "undefined"){
        Vxhr = new XDomainRequest();
        xhr.open(method,url);
    }else{
        xhr = null;
    }
    return xhr;
}

Comet

一种服务器向页面推送数据的技术。实现Comet的两种方式:长轮询(利用setTimeout)和流(浏览器向服务器发送一个请求,服务器保持连接断开,然后周期性的向浏览器发送数据)。
使用XHR对象实现HTTP流:

function createStreamingClient(url,progress,finished){
    var xhr = new XMLHttpRequest(),
        received = 0;
    xhr.open("get",url,true);
    xhr.onreadystatechange = funtion(){

        var result;
        if(xhr.readyState == 3){
            result = xhr.responseText.subString(received);
            received += result.length;
            //调用progress回调函数
        }else if(xhr.readyState == 4){
            finished(xhr.responseText);
        }

    }
    xhr.send(null);
    return xhr;
}

服务器发送事件

SSE(Server-Send Events,服务器发送事件)是围绕只读Comet交互推出的API。SSE API用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的MIME类型必须是text/event-stream。支持SSE的浏览器:firefox6+,safari5+,opera11+,chrome
1. SSE API
首先创建一个新的EventSource对象。

// 传入的url必须是同源的
var source = new EventSource("myevents.php");

EventSource的实例有个readyState属性,值为0表示正连接服务,1表示打开了连接,2表示关闭了连接。
还有以下3个事件:
open:在建立连接时触发。
message:在从服务器接收到新事件时触发。
error:在无法建立连接时触发

source.onmessage = function(event){
    var data = event.data;
    //处理数据
    //如果连接断开会自动重新连接,如果想强制断开连接。可close()方法
    source.close();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值