【JavaScript从入门到精通】第二十三课 AJAX中级

此内容来自开课吧石川微信公众号

上节课我们讲解了AJAX基础,其中我们在使用AJAX时用的是已经编写好的AJAX库,这节课我们开始学习A如何自己编写一个AJAX库。

编写AJAX

通过AJAX从服务器获取数据,需要以下几步:

  • 创建AJAX对象
  • 连接到服务器
  • 发送请求
  • 接收返回值

那么,实现这个过程应该如何编写呢?我们从第一步创建AJAX对象写起:

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="utf-8">
    <title>无标题文档</title>
    <script>
    window.onload=function ()
    {
        var oBtn=document.getElementById('btn1');
        oBtn.onclick=function ()
        {
            //1.创建Ajax对象
            //非IE6
            var oAjax=new XMLHttpRequest();
    
            //IE6
            //var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
    
            alert(oAjax);
        };
    };
    </script>
  </head>
  <body>
    <input id="btn1" type="button" value="读取" />
  </body>
</html>

可以看到点击按钮后,会返回一个XMLHttpRequest对象,这就是我们的AJAX对象。不过XMLHttpRequest只兼容非IE6的浏览器,兼容IE6的写法为:var oAjax=new ActiveXObject(“Microsoft.XMLHTTP”)。ActiveX是IE6的一个插件,在IE6下AJAX是通过这个插件来完成工作的。

if(XMLHttpRequest)
        {
            var oAjax=new XMLHttpRequest();
        }
        else
        {
            var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
        }

可是,当我们进行这样的if判断时,会发现在IE6下又出现了问题。这是为什么呢?

为了说明这个问题,我们需要看一个JS里很有意思的特点。

var a=12;alert(window.a);

我们平时在使用全局变量时,基本是直接使用,实际上我们这里在变量前加了window,也没有发生任何变化。其实,我们定义的任何全局变量都属于window下的一个属性,而且alert方法本身也属于window。

var a=12;window.alert(window.a);

现在我们来看这么个例子:

alert(a);
alert(window.a);

我们虽然说过,加不加window看上去没有任何区别,但在这里,前者会直接报错,后者会返回undefined。这是因为在JS里,如果使用没有被定义的变量,浏览器会报错;而如果是没有被定义的属性,则不会报错,只是返回undefined。

回到我们的AJAX上。在非IE6浏览器下,我们的代码中的XMLHttpRequest是被定义过的,自然没有问题,可以通过。但在IE6下XMLHttpRequest是没有被定义的,因此会报错,不过如果我们:

if(window.XMLHttpRequest)
    {
        var oAjax=new XMLHttpRequest();
    }
        else
    {
        var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
    }

在XMLHttpRequest前加上window的话,尽管XMLHttpRequest依然没有被定义,但它由一个变量变为了一个属性,返回的是undefined,正好是我们想要的。

创建好ajax对象后,我们就需要连接服务器了,连接服务器的过程非常简单,只需要一步:

oAjax.open('GET','a.txt',true);

ajax用open方法连接服务器,它有三个参数:第一个参数是连接方法,也就是我们前面表单中提到的get或者post,这里我们一般采用get方法;第二个参数是文件名,也就是我们需要读取的文件(为了避免缓存我们可以在文件后面加入时间戳);第三个参数是异步传输,这里需要对同步和异步的区别进行一下讲解。

简单来说,在JS里,同步指事务一件一件进行,而异步则指多件事务同时进行。AJAX天生就是用来进行异步操作的,如果AJAX工作在同步方式下,我们如果向服务器发送了一个请求,在服务器回复之前,页面的所有其它功能都不能正常运行。而异步则可以避免这种情况——正如你在微博页面发送了一条微博,如果服务器反应较慢不能马上发送成功,在这个过程中你依旧可以给别人点赞,评论别人。在大部分情况下,ajax都是采用异步的方式(这个参数如果为true的话即为异步,flase的话即为同步)。

连接到我们的服务器之后,我们将进行第三步:发送请求。发送请求的方式也非常简单,我们只需要调用一个send()方法即可。

oAjax.send();

然后是我们的第四步:接收返回信息。

oAjax.onreadystatechange=function(){
        if(oAjax.readyState==4)
            {
                if(oAjax.status==200)
                {
                    alert('成功'+responseText);
                }
                else{
                    alert('失败'+oAjax.status);
                }
            }
          }

oAjax.readyState代表了请求的状态,其中数字代表的含义如下:

  • 0 (未初始化)还没有调用open()方法
  • 1 (载入)已调用send()方法,正在发送请求
  • 2 (载入完成)send()方法完成,已收到全部响应内容
  • 3 (解析)正在解析响应内容
  • 4 (完成)响应内容解析完成,可以在客户端调用了

当readyState的值等于4时,代表读取完成——值得注意的是,完成不等于成功,为了进一步对是否成功进行判断,我们就用到了另一个属性:status(状态码)。只有status等于200的时候,才代表通信的成功。

最后,我们为了获取读取回来的信息,我们还需要用到AJAX的一个属性:responseText,也就是从服务器响应发回的文本。

这样我们就完成了一个AJAX库,只要把上面的代码封装为一个函数就可以进行引用了。

function ajax(url, fnSucc, fnFaild){
    //1.创建Ajax对象
    if(window.XMLHttpRequest)
    {
        var oAjax=new XMLHttpRequest();
    }
    else
    {
        var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
    }
    //2.连接服务器
    //open(方法, 文件名, 异步传输)
    oAjax.open('GET', url, true);
    //3.发送请求
    oAjax.send();
    //4.接收返回
    oAjax.onreadystatechange=function ()
    {
        //oAjax.readyState  //浏览器和服务器,进行到哪一步了
        if(oAjax.readyState==4) //读取完成
        {
            if(oAjax.status==200)   //成功
            {
                fnSucc(oAjax.responseText);
            }
            else
            {
                if(fnFaild)
                {
                    fnFaild(oAjax.status);
                }
                //alert('失败:'+oAjax.status);
            }
        }
    };
}

最后,我们来说两个注意事项。

首先是数据类型。数据类型有xml,json等,其中xml在老式程序里用的比较多,但同等数据量的情况下xml要比json大的多,因此xml已经逐渐被抛弃。而目前的JS几乎都是采用的JSON这种数据类型进行交互了。

另一点是关于字符集:我们需要将我们所有的文件统一成一种字符集(一般为UTF-8)。

如需转载,烦请注明出处:https://www.qdskill.com/javascript/4423.html

发表评论

登录后才能评论