Ajax和Comet

来源:互联网 发布:淘宝网充值平台网址 编辑:程序博客网 时间:2024/06/07 09:25

Ajax是一种异步请求数据的技术,请求数据时不用刷新整个界面。

核心API:XMLHttpRequest

在IE7以前的浏览器上需要通过ActiveX来创建Ajax对象;
现在IE7和以上版本以及其他浏览器都支持XMLHttpRequest对象了

通用创建方式:

function createXHR() {    if (typeof XMLHttpRequest != "undefined") {        return new XMLHttpRequest();    } else if (typeof ActiveXObject != "undefined") {        if (typeof arguments.callee.activeXString != "string") {            //IE中可能遇到三种不同版本的XHR对象            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) {                    //跳过                }            }        }        return new ActiveXObject(arguments.callee.activeXString);    } else {        throw new Error("No XHR object available.");    }}

new XMLHttpRequest()
new ActiveXObjecet(versionName)

XHR对象的使用

var xhr = createXHR();

open方法

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

接收三个参数:
参数1:http请求方法,get/post等
参数2:URL(这里是相对当前页面的路径,当然也可以是绝对路径)
参数3:表示是否异步发送请求的布尔值

send方法

在设置好open后,需要调用send方法去发送请求

xhr.open("get", "example.txt", false);xhr.send(null);

send方法接收一个参数,即要作为请求实体发送的数据(post的请求参数都在实体中),通常get请求传null,post请求传序列化表单数据

GET请求

URL参数形式是?+&

function addURLParam(url, name, value) {    url += (url.indexOf("?") == -1 ? "?" : "&");    url += encodeURIComponent(name) + "=" + encodeURIComponent(value);    return url;}

post请求

添加实体(表单数据)
参数中只有&连接符

function submitData() {    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: " + xhr.status);            }        }    };    xhr.open("post", "postexample.php", true);    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");    var form = document.getElementById("user-info");    xhr.send(serialize(form));}

发送完请求后如何获取返回信息

可以通过XHR的以下属性获取

responseText :作为响应主体被返回的文本。
status :响应的 HTTP 状态。
statusText :HTTP 状态的说明
responseXML :如果响应的内容类型是 “text/xml” 或 “application/xml” ,这个属性中将保存包含着响应数据的 XML DOM 文档。对于非 XML 数据而言, responseXML 属性的值将为 null

同步请求

获取响应信息,首先需要判断响应状态码

xhr.open("get", "example.txt", false);xhr.send(null);if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {    alert(xhr.responseText);} else {    alert("Request was unsuccessful: " + xhr.status);}

异步请求

以上对于同步请求可以直接在发送请求后获取返回数据,然而对于异步请求就需要添加监听响应事件: 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: " + xhr.status);        }    }};xhr.open("get", "example.txt", true);xhr.send(null);

其中 readyState的状态码是:
 0 :未初始化。尚未调用 open() 方法。
 1 :启动。已经调用 open() 方法,但尚未调用 send() 方法。
 2 :发送。已经调用 send() 方法,但尚未接收到响应。
 3 :接收。已经接收到部分响应数据。
 4 :完成。已经接收到全部响应数据,而且已经可以在客户端使用了。

在接收到响应前取消请求

xhr.abort()

HTTP头

添加请求头

xhr.setRequestHeader("MyHeader", "MyValue");

获取响应头

var myHeader = xhr.getResponseHeader("MyHeader");var allHeaders = xhr.getAllResponseHeaders();

XMLHttpRequest2

并非所有浏览器都支持
对XMLHttpRequest进行了扩展
支持 FormData 的浏览器有 Firefox 4+、Safari 5+、Chrome 和 Android 3+版 WebKit。

扩展一:提供了表单处理API

FormData类型:获取表单中序列化参数

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

于是可以不用手动去实现序列化了,上面的代码也可以替换成:

...省略xhr.send(new FormData(form));

扩展二:超时属性和响应事件

xhr.timeout = 1000; // 将超时设置为 1  秒钟(仅适用于 IE8+ )xhr.ontimeout = function(){alert("Request did not return in a second.");};

扩展三:进度响应事件

 loadstart :在接收到响应数据的第一个字节时触发。
 progress :在接收响应期间持续不断地触发。
 error :在请求发生错误时触发。
 abort :在因为调用 abort() 方法而终止连接时触发。
 load :在接收到完整的响应数据时触发。
 loadend :在通信完成或者触发 error 、 abort 或 load 事件后触发。

xhr.onload = function() {    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {        alert(xhr.responseText);    } else {        alert("Request was unsuccessful: " + xhr.status);    }};

创建进度指示器

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

跨资源共享

IE中需要使用新的API:XDomainRequest
其他浏览器xhr支持,不过其他属性受到限制

IE对跨域的支持

XMLHttpRequest和XDomainRequest的区别:

cookie 不会随请求发送,也不会随响应返回。
只能设置请求头部信息中的 Content-Type 字段。
不能访问响应头部信息。
只支持 GET 和 POST 请求。
 只支持异步请求,所以open方法只有两个参数

导致跨域失败的原因很多,需要处理error事件

var xdr = new XDomainRequest();xdr.onload = function() {    alert(xdr.responseText);};xdr.onerror = function() {    alert("An error occurred.");};xdr.timeout = 1000;xdr.ontimeout = function() {    alert("Request took too long.");};xdr.open("get", "http://www.somewhere-else.com/page/");xdr.send(null);

post请求添加唯一的请求头

var xdr = new XDomainRequest();xdr.onload = function() {    alert(xdr.responseText);};xdr.onerror = function() {    alert("An error occurred.");};xdr.open("post", "http://www.somewhere-else.com/page/");xdr.contentType = "application/x-www-form-urlencoded";xdr.send("name1=value1&name2=value2");

其他浏览器跨域原生支持

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: " + xhr.status);        }    }};xhr.open("get", "http://www.somewhere-else.com/page/", true);xhr.send(null);

注意以下限制:

 不能使用 setRequestHeader() 设置自定义头部。
 不能发送和接收 cookie。
 调用 getAllResponseHeaders() 方法总会返回空字符串。

其他跨域技术

用到时再说吧

0 0