Ajax知识点

XMLHttpRequest对象

Ajax的核心是XMLHttpRequest。

        //适用于IE7之前的版本
        function creatXHR(){
            if(typeof arguments.callee.activeXString != "string"){
                var version = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],i,len;
                for(i=0,len=version.length;i<len;i++){
                    try{
                        new ActiveXObject(version[i]);
                        arguments.callee.activeXString = version[i];
                        break;
                    } catch (ex){
                        //跳过
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString);
        }

支持更高版本的写法:

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

这个函数中新增的代码首先检测原生XHR对象是否存在。如果存在则返回它的 新实例。如果原生对象不存在,则检测ActiveX对象。如果这两种对象都不存在,就抛出一个错误。然后就可以使用以下的代码在所有浏览器中创建XHR对象了

var xhr = createXHR();

XHR的用法

使用xhr对象时,要调用 的第一个方法是open(),它接受3个参数:要发送的请求类型,请求的URL和表示是否异步发送请求的布尔值。

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

要发送特定的请求,像下面这样调用 seng()方法

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

这里的send()方法接收一个参数,即要作为请求的主体发送的数据。如果不需要通过请求主体发送数据,则必须传入null.

相关的属性:

responseText:作为响应主体被返回的文本

responseXML:如果响应的内容是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的XML DOM文档

status: 响应的 HTTP状态

statusText:HTTP状态的说明

在接收到响应后,第一步是检查status属性,以确定响应已经 成功返回。一般来说,将HTTP状态代码为200作为成功的标志。

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

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

只要readyState属性的值由一个值变成另一个值,都会触发一readystatechange事件。可以利用这个事件来检测每次状态变化 

后的readyState的值.

        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);

另外,可以调用abort()方法来取消异步请求

xhr.abort()

HTTP头部信息

每个HTTP请求和响应都会带有相应的头部信息。

默认请问下,在发送xhr请求的同时, 还会发送下列头部信息:

Accept:浏览器能够处理的内容类型

Accept-Charset:浏览器能够显示的字符集

Accept-Encoding:浏览器能够处理的压缩编码

Accept-Language:浏览器 与服务器之间连接的类型

Cookie:当前页面设置所在的域

Referer:发出请求的 页面的URI。

User-Agent:浏览器的用户代理字符串

使用setRequestHeader()方法可以设置自定义的请求头部信息。这个方法接受两个参数:头部字段的名称和头部字段的值。要成功发送头部请求,必须在调用 open()之后且调用 send()之前,如下:

        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.setRequestHeader("MyHeader","MyValue");
        xhr.send(null);

调用XHR对象的getResponseHeader()方法并传入头部字段名称,可以取得相应的响应头部信息。而调用getAllResponseHeaders()方法可以取得一个包含所有头部信息的长字符串。

        var myHeader = xhr.getResponseHeader("MyHeader");
        var allHeader = xhr.getAllResponseHeader();

GET请求

get请求是最常见的请求类型,最常用于向服务器查询某些信息。

使用get请求经常会发生一些错误,就是查询字符串的格式有问题。

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

下面这个函数可以辅助向 现有URL的末尾添加查询字符串参数:

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

这个addURLParam函数接收3个参数:要添加参数的URL,参数的名称和参数的值。

下面是使用这个函数来构建请求URL的示例:

        var url = "example.txt";
        //添加参数
        url = addURLParam(url, "namne", "Nicholas");
        url = addURLParam(url, "book", "Prefessional Javascript");
        //初始化请求
        xhr.open("get", url, false);

 

POST请求

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

POST请求应该把数据作为请求的主体提交,而GET请求传统上不是这样。

xhr.open("post","example.php",true);

发送POST请求的第二步就是向send()方法中传入某些数据。

        function submitData(){
            var xhr = creatXHR();
            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));



FormDat

FormData为序列化表单以及创建与表单格式相同的数据提供了便利。下面的代码创建了一个FormData对象,并向其中添加了一些数据:

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

这个append方法接收两个参数:键和值

也可以用表单元素的数据先向其中填入键值对:

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

创建了FormData实例后,可以将它直接传给XHR的send()方法,如下;

        var xhr = creatXHR();
        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);
        var form = document.getElementById(user-info);
        xhr.send(new FormData(form));

使用FormData的方便之处体现在不必明确地在XHR对象上设置请求头部。XHR对象能够识别传入的数据类型是FormData的实例,并配置适当的头部信息。

 

超时设定 timeout属性

IE8为XHR对象添加了一个timeout属性,表示请求在等待响应多少毫秒之后就终止。

        var xhr = creatXHR();
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                try{
                    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                        alert(xhr.responseText);
                    } else {
                        alert("Request was unsuccessful:" + xhr.status);
                    }
                } catch(ex){
                    //假设由ontimeout事件处理程序处理
                }
            }
        }
        xhr.open("post","timeout.php",true);
        xhr.timeout = 1000;//将超时设置为1s
        xhr.ontimeout = function(){
            alert("Request did not return in a second.")
        };

 

overrideMimeType()方法

该方法用于重写XHR响应的MIME类型。

比如,服务器返回的MIME类型是text/plain,但数据中实际包含的是XML。根据MIME类型 ,即使数据是XML,responseXML属性中仍然是null。通过调用overrideMimeType()方法,可以保证把响应当作XML而非纯文本来处理。

        var xhr = createXHR();
        xhr.open("get","text.php",true);
        xhr.overrideMimeType("text/xml");
        xhr.send(null);

进度事件

6个进度事件:

loadstart:在接收到响应数据的第一个字节时触发

progress:在接收响应期间持续不断地触发

error:在请求发生错误时触发

abort:在因为调用abort()方法而终止连接时触发

load:在接收到完整的响应数据时触发

loadend:在通信完成或者触发error,abort或事件后触发

 

跨资源共享 CORS

cors的基本思想是,就是用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。

IE对CORS的实现 

所有XDR请求都是异步执行,不能用它来创建同步请求。如下:

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

要检测错误,可以像下面指定一个onerror事件处理程序

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

在请求 返回前调用abort()方法可以终止请求:

        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请求,XDR对象提供了contentType属性,用来表示发送数据的格式。

        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("name=vauel1&name2=value2");

其他浏览器对CORS的实现

var xhr = creatXHR();
            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);
                    }
                }
            }

        xdr.open("get", "http://www.somewhere-else.com/page/",true);
        xdr.send(null);


Preflighted Reqeusts

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

 

带凭据的请求

默认情况下,跨源请求不 提供凭据(cokie,HTTP认证及客户端SSL证明等)。通过withCredentials属性设置为true.可以指定某个请求应该发送凭据。如果服务器接受凭据的请求,会用下面的HTTP头部来响应:

Access-Control-Allow-Credentials: true;

跨浏览器的CORS

检测XHR是否支持CORS的最简单的方式,就是检查是否存在withCredentials属性。再结合检测XDomainRequest对象是否存在,就可以兼顾所有浏览器了。

        function createCORSRequest(method, url) {
            var xhr = new XMLHttpRequest();
            if ("widthCredentials" in xhr) {
                xhr.open(method, url, true);
            } else if (typeof XDominRequest != "undefined") {
                xhr = new XDominRequest();
                xhr.open(method, url);
            } else {
                xhr = null;
            }
            return xhr;
        }
        var request = createCORSRequest("get", "http://www.somewhere-else.com/page/");
        if (request) {
            request.onload = function() {
                //...
            };
            request.send();
        }

XMLHttpRequest和XDominRequest这两个对象的共同的属性/方法如下:

abort():用于停止正在进行的请求

onerror:用于检测错误

onload:用于检测成功

responseText:用于取得响应内容

send():用于发送请求

 

图像Ping

动态创建图像经常用于图像Ping.图像Ping是与服务器进行简单,单向的跨域通信的一种方式。请求的数据是通过查询字符串形式发送的,而响应可以是任意内容。

        var img = new Image();
        img.onload = img.onerror = function(){
            alert("Done!");
        };
        img.src = "http://www.example.com/test?name=Nicholas";

JSONP

JSONP是JSON with padding(填充式JSON或参数式JSON)的简写。

JSONP由两部分组成:回调函数和数据。

        function handleResponse(response){
            alert("You re at Ip address" + response.ip + ",whihc 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);

这个例子通过查询地理定位服务来显示你的IP地址和位置信息。

 

Comet

Ajax是一种从页面向服务器请求数据的技术,而Comet则是一种服务器向页面推送数据的技术。

有两种实现Comet的方式:长轮询和流。

通过侦听readystatechange事件检测readyState的值是否为3,就可以利用XHR对象实现HTTP流。随着不断从服务器接收数据,readyState的值会周期性地变为3.当readyState值变为3时,responseText属性中就会保存接收到的所有数据。此时,就需要比较 较此前接收到的数据,决定从什么位置开始取得最新的数据。使用XHR对象实现HTTP流的典型代码如下:

        function 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回调函数
                    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!");
        });

这个createStreamingClient()函数接收三个参数:要连接的URL,在接收到数据时 调用的函数以及关闭连接时调用的函数。有时候,当连接关闭时,很可能还需要重新建立,所以关注连接什么时候关闭还是有必要的。

 

服务器发送事件 SSE

SSE是围绕只读Comet交互推出的API或者模式。

SSE API用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。

服务器响应的MIME类型必须是text/event-stream.

SSE支持短轮询,长流询和HTTP流。

SSE API

要预定新的事件流,首先要创建一个新的EVentSource对象,并传进一个入口点:

var source = new EventSource("myevents.php");

注意,传入的URL必须与创建对象的页面同源(相同的URL模式,域及端口)。EventSource的实例有一个readyState属性,值为0表示正连接到服务器,值为1表示打开了连接,值为2表示关闭了连接。另外还有3个事件:

open:在建立连接时触发

message:在从服务器接收到新事件时触发

error:在无法建立连接时触发

        source.onmessage = function(event){
            var data = event.data;
            //处理数据
        }
        source.close();//断开连接

事件流

所谓的服务器事件会通过一个持久的HTTP响应发送,这个响应的MIME类型为text/event-stream.响应的格式为纯文本。

        data: foo
        data: bar 
        data: foo
        data: bar

 

Web Sockets

Web Sockets的目标是在一个单独的持久连接上提供全双工、双向通信。

1. Web SocketsAPI

要创建Web Socket,先实例一个WebSocket对象并传入要连接的URL:

var socket = new WebSocket("ws://www.example.com/server.php");

Web Socket 表示当前状态的属性:

WebSocket.OPENING(0): 正在建立连接

WebSocket.OPEN(1):已经建立连接

WebSocket.CLOSEING(2):正在关闭连接

WebSocket.CLOSE(3):已经关闭连接

 WebSocket没有readystatechange事件,不过,它有其他事件,对应着不同的状态。readyState的值永远从0开始。

要关闭Web Socket连接:

socket.close();

发送和接收数据

        var socket = new WebSocket("ws://www.example.com/server.php");
        socket.send("Hello World!");

因为Web Socket只能通过连接发送纯文本数据,所以对于复杂的数据结构,在通过连接之前,必须进行序列化:

        var message = {
            time: new Data(),
            text: "Hello World!",
            clientId: "asdfp8734rew"
        };
        socket.send(JSON.stringify(message));

当服务器向客户端发来消息时,WebSocket对象就会触发message事件:

        socket.onmessage = function(event){
            var data = event.data;
            //处理数据
        }

WebSocket其他事件

open:在成功 建立连接时触发

error:在发生错误时触发,连接不能持续

close:在连接关闭时触发

        var socket = new WebSocket("ws://www.example.com/server.php");
        socket.onopen = function(){
            alert("Connection established.");
        };

        socket.onerror = function() {
            alert("Connection error.");
        };

        socket.onclose = function() {
            alert("Connection closed.");
        };

可以记录到日志中以便将来分析:

        socket.onclose = function(event){
            console.log("Was clear?" + event.wasClean + "Code = " + event.code + " Reason= " + event.reason);
        };

 

 

Ajax是无需刷新页面就能够从服务器取得数据的一种方法。从以下几方面了解: 

(1).负责Ajax运作的核心对象是XMLHttpRequest(XHR)对象

(2).XHR对象由微软最早在IE5中引入,用于通过Javascript从服务器取得XML对象

(3).在此之后,各浏览器都实现了相同的特性,使XHR成为了Web的一个事实标准

(4).虽然浏览器的实现之间有差异,还是相对规范,放心使用

Comet是对Ajax的进一步扩展,让服务器几乎能够实时地向客户端 推送数据。实现Comet手段主要有两个:长轮询和HTTP流。

Web Sockets是一种与服务器进行全双工,双向通信的信道。与其他方案不同,它不使用HTTP,而是使用一种自定义的。具有速度上的优势。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值