封装自己的框架kylinGo——GET操作篇

ajax操作在前端工作中必不可少,其重要性我就不再赘述,而常用的几乎每一种框架都有ajax的封装实现。而我们要做的,是用原生代码实现GET和POST方法,再封装成简单的形式以方便调用。这要求我们对原生ajax有一些了解,面试中也经常会谈到原生ajax部分。

假设你对ajax的使用场景和功能已经比较了解。下面我来对ajax进行一些技术层面的简要介绍

ajax其本质是通过一个对象来向某个服务器发出异步请求,获取数据,并执行回调函数的过程。

同步和异步

同步请求:严格按照时间顺序发出请求,等待请求结果,执行回调函数,向下执行

异步请求:发起请求后,等待请求结果的同时向下执行其他javascript代码,返回请求结果后,执行回调函数

可以看到,相比于同步请求,异步请求可以节约时间,提高效率,因此ajax请求全部采用异步方式执行。此处请注意javascript语言本身是单线程的,即同一时刻,只能有一段代码在执行,不具备异步特性。ajax的异步指的是:javascript通过XmlHttpRequest对象,向浏览器发出请求,并将回调函数交给浏览器,由浏览器开启另一个线程去管理http请求的发送,当http结果返回后,执行回调函数

XmlHttpRequest对象

这个对象名字很长,但是却是一个很简单的对象,接下来我将介绍这个对象中非常重要的几个属性和方法,了解了这些属性和方法后,我们也就具备了封装get请求的能力。

open方法将设置本次请求的方式,它接受三个参数,第一个参数指定了ajax向服务器提交数据的类型,即post还是get。第二个参数指定了通信地址,最后一个参数指定是否启用异步方式,默认是启用的。

//创建XmlHttpRequest对象
var xhr = new XMLHttpRequest();
//通过open方法指定请求方式
xhr.open('GET', 'http://example.com?id=1', true);

通过以上代码,我们已经设置好了一个GET请求所需要的全部要素,接下来我们可以发送请求了

//发送请求
xhr.send()

通过send方法,我们已经将请求发送给了服务器,接下来我们就要等待服务器的反应。XmlHttpRequest中有一个重要的属性叫做readyState,它表示对象当前的状态,而且它会随着对象状态的改变而动态更新,例如,当readyState属性值为2时,表示数据已经发送,但还未收到服务器响应。当readyState为4时表示服务器返回数据已经接收完毕。

另外,每当readyState改变时,都会调用onreadystatechange函数。我们可以通过重写onreadystatechange函数,来检测GET请求是否完成:

//重写onreadystatechange函数,监测请求是否完成
xhr.onreadystatechange = function(){
    //如果请求已经发出,但还未收到响应
    if(xhr.readyState == 3){
        console.log("数据已经发送,正在等待响应");    
    }
    //如果已经收到响应
    if(xhr.readyState == 4){
        //http状态码为200表示服务器响应成功
        if(xhr.status == 200){
            console.log("success");
            //打印服务器的反馈
            console.log(xhr.responseText);
        } else {
            console.log("failed");
            console.log(xhr);
        }
    }
}

上文中提到的status状态表示服务器返回的http状态码,如果status为200表示返回成功,404表示未找到文件,500表示服务器内部错误等。

responseText则会被写入服务器的返回数据

至此,我们已经掌握了封装GET请求所需的全部知识,现在我们将GET请求写入kylinGo框架

var kylin = (function(){
        dom:function(dom){
            return document.querySelector(dom)
        },
        domAll:function(dom){
            return document.querySelectorAll(dom);
        },
        get:function(path,data,callback){
            //构造get请求地址
            var str = "?"
            for(var index in data){
                str += index + "=" + data[index] + "&";
            }
            str = str.substring(0,str.length-1);

            var xhr = new XMLHttpRequest();
            xhr.open('GET', path+str,  true);
            xhr.send(null);
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    if(xhr.status == 200){
                        console.log("success");
                        //用回调函数处理服务器返回的数据
                        callback(xhr);
                    } else {
                        console.log("failed");
                        console.log(xhr);
                    }
                }
            }
        }
    }
}())