【JavaScript】-原生JavaScript实现Ajax

Ajax(Asynchronous JavaScript +XML),能够想服务器请求额外的数据而无需卸载页面,会带来更好的用户体验。
Ajax技术的核心是 XMLHttpRequest(XHR)对象,IE5是第一款引入XHR对象的浏览器,在IE5中,XHR对象是通过MSXML库中的一个ActiveX对象实现的。

一、XHR1级

1、创建XHR对象,要兼容IE5,需要将其封装在一个函数中。

//创建XHR对象(兼容IE5以前)
function createXHR(){
    if (typeof XMLHttpRequest != "undefined") {
        return new XMLHttpRequest();//IE5以上版本直接创建XHR对象
    } else if (typeof ActiveXObject != "undefined") {
        if (typeof arguments.callee.activeXString != "string") {
            var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"];
            var i;
            var len =versions.length;
            for (i = 0; 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.")
    }
}

var xhr = createXHR();//使用该函数

这个函数的代码,首先检测原生XHR对象是否存在,如果存在返回它的实例,如果原生对象不存在,则检测ActiveX对象,如果这两种都不存在,就抛出一个错误。

2、XHR的用法

1.调用open(要发送的请求的类型,请求的URL,是否异步发送的布尔值)
注意:URL是相对于执行代码的当前页面,当然也可是绝对路径。只能向同一个域中使用相同端口和协议的URL发送请求,即不可跨域。
2. 要发送特定的请求,调用send()。send接受一个参数,即要作为请求主体发送的数据。

3、XHR对象的属性

浏览器发送请求,服务器进行响应,收到响应后,响应的数据会自动填充XHR对象的属性,相关属性介绍:

responseText:作为相应主体被返回的文本
responseXML:如果响应的内容类型是“text/xml”或者”application/xml”,这个属性中将保存包含响应数据的XML DOM文档
status: 响应的HTTP状态
常见的状态码:
      200 – 服务器成功返回网页
      404 – 请求的网页不存在
      503 – 服务不可用
      1xx(临时响应)— 表示临时响应并需要请求者继续执行操作的状态代码。
       2xx (成功)— 表示成功处理了请求的状态代码。
      3xx (重定向) — 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
       4xx(请求错误)— 这些状态代码表示请求可能出错,妨碍了服务器的处理。
       5xx(服务器错误) — 这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。

statusText:HTTP状态的说明

注:要通过检测status来决定下一步要做什么,不要依赖于statusText,因为后者在跨浏览器使用时不太靠谱

4.readyState属性

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

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

只要readyStatue 属性的值由一个变为另一个,就会触发一次readys
tatechange事件,可以利用这个事件来检测每次状态变化后readyState的值。

var xhr = createXHR();
xhr.onreadystatechange = function(){
    if (xhr.readyState == 4) {
        if (xhr.status >=200 || xhr.status == 304 ) {
            console.log(xhr.responseText);
        } else {
            console.log("Request was unsuccessful:" + xhr.status);
        }
    }
}
xhr.open("post","index.php",true);
xhr.send(null);

可以使用xhr.abort()取消异步请求

5、HTTP头部信息

默认情况下,在发送XHR请求的同时,还会发送如下头部信息:
这里写图片描述

Accept:浏览器能够处理的内容类型
Accept-Charset:浏览器能够显示的字符集
Accept-Encoding:浏览器能够处理的压缩编码
Accept-Language:浏览器当前设置的语言
Connection:浏览器与服务器之间的连接类型
Host:发出请求的页面所在的域
Referer:发出请求的页面的URL

使用setRequestHeader()方法可以设置自定义的请求头部信息
这个方法接收两个参数:头部字段的名称和头部字段的值,必须在调用open()之后且调用send()之前调用该函数
使用getResponseHeader()方法并传如头部字段名称,可以得到相应的响应头部信息

二、XHR2级

    XHR1级只是把已有的XHR对象的实现细节描述了出来,而XHR2级则进一步发展了XHR。

1、FormData

FormData为序列化表单及创建于表单格式相同的数据提供了便利。使用FormData的方便之处在于不必明确的在XHR对象上设置请求头部,XHR对象能够识别传入的数据类型是FormData的实例,并配置适当的头部信息。

var xhr = createXHR();//创建xhr对象
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
        if (xhr.status >= 200 && xhr.status <300 || xhr.status == 304) {
            console.log(xhr.responseText);
        } else {
            console.log("Request was unsuccessful:" + xhr.status);
        }
    }
};
xhr.open("post","index.php",true);
var form = document.getElementById("user-info");
send(new FormData(form));

2、超时设定

IE8为XHR对象添加了一个timeout属性,表示请求在等待响应多少毫秒之后就终止。在给timeout设置一个数值后,如果在规定时间内浏览器还没有接收到相应,那么就会出发timeout事件,进而会调用ontimeout事件处理程序。
Note:只适用于IE8

var xhr = createXHR();//创建xhr对象
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
        if (xhr.status >= 200 && xhr.status <300 || xhr.status == 304) {
            console.log(xhr.responseText);
        } else {
            console.log("Request was unsuccessful:" + xhr.status);
        }
    }
};
xhr.open("get","index.php",true);
xhr.timeout = 1000;//将超时设置为1秒
xhr.ontimeout = function(){
    alert("Request did not return in one second");
}
send(null);

3、overrideMimeType( )

Firefox 最早引入了该方法,其用于重写XHR响应的MIME类型。由于返回响应的MIME类型决定了XHR对象如何处理它,所以提供一种方法能够重写服务器返回的MIME类型是很有用的。

MIME:MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

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

这个例子强迫XHR对象将响应当作XML而非纯文本来处理。

三、进度事件 Progress Events

Progress Events 规范是W3C的一个工作草案,最初只针对XHR操作,定义了与客户点服务器通信有关的事件,目前也被其他API借鉴。有以下6个进度事件:

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

每个请求都从loadstart事件开始,接下来是一或多个progress事件,然后触发error、abort、或者load中的一个,最后以出发loadend事件结束

1、load事件(Firefox/Opera/Chrome/Safari都支持)

Firefox在实现XHR对象的某个版本时,用以替代readystatechange事件。响应接收完毕后将出发load事件,因此也就没有必要去检查readyState属性了onload事件处理程序会接收到一个event对象,其target属性指向XHR对象实例,因此可以访问到XHR对象的所有方法和属性。
Note:只要浏览器接收到服务器的响应,不管其状态如何,都会出发load事件,因此,必须要检查status属性,才能确定数据是不是真的已经可用了。

var xhr = createXHR();//创建xhr对象
xhr.onload = function () {//onload事件处理函数
    if (xhr.status >= 200 && xhr.status <300 || xhr.status == 304) {
        console.log(xhr.responseText);
    } else {
        console.log("Request was unsuccessful:" + xhr.status);
    }
};
xhr.open("get","index.php",true);
send(null);

2、progress事件

这个事件会在浏览器接收新数据期间周期性的触发。onprogress事件处理程序会接收到一个event对象,其target属性是XHR对象,其还包含着三个额外的属性:lengthComputable(表示进度信息是否可用的布尔值)、position(表示已经接受的字节数)、totalSize(根据Content-Length响应头部确定的预期字节数)

为用户创建进度指示器:

var xhr = createXHR();//创建xhr对象
        xhr.onload = function (event) {//onload事件处理函数
            if (xhr.status >= 200 && xhr.status <300 || xhr.status == 304) {
                console.log(xhr.responseText);
            } else {
                console.log("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";  
            }
        };
        xhr.open("get","info.json",true);
        xhr.send(null);

四、请求类型

1、get请求

最常见的请求类型,最常用于向服务器查询某些信息。对于XHR而言,位于传入open()方法的URL末尾的查询字符串必须经过正确的编码才行。
查询字符串中每个参数的名称和值都必须使用endodeURLComponent()进行编码,然后才能放到URL末尾,并且 所有名-值对儿都必须由&分隔

如:example.php?name1=value1&name2=value2
向URL末尾添加查询字符串的函数:

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

这个函数首先检查URL是否包含问号,如果没有,就添加一个问号;否则,添加一个和号。然后,将参数名和值进行编码,再添加到URL的末尾。

2、post请求

通常用于向服务器发送应该被保存的数据,post请求的主体可以包含非常多的额数据,而且格式不限。

默认情况下,服务器对POST请求和Web表单提交的请求不会一视同仁,但是我们可以用XHR来模仿表单提交:首先,将Content-Type头部信息设置为application/x-www-form-urlencoded,也就是表单提交时的内容类型,其次是一适当的格式创建一个字符串

function submitData () {
    var xhr = createXHR();
    xhr.onreadystatechange = function () {
        if (xhr.resdyState == 4) {
            if (xhr.status >= 200 && xhr.status <300 || xhr.status == 304) {
                console.log(xhr.responseText);
            } else {
                console.log("Request was unsuccessful:" + xhr.status);
        }
    };
    xhr.open("post","index.php",true);
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//模仿表单提交
    var form = document.getElementById("user-info");
    xhr.send(new FormData(form));
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值