ajax发送异步请求从入门到精通

ajax发送异步请求

一、什么是ajax

  AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。
也就是说ajax和我们在浏览器地址栏,或者通过form表单发送请求一样,ajax也可以发送请求,但是二者有很大的不同,ajax不用刷新界面,发送异步请求。


二、发送ajax get请求的步骤

 ① 创建异步对象 
var  xhr =new XMLHttpRequest();

 ② 设置URL
xhr.open('get',"index.php",true);
// 参数1:发送请求方式
// 参数2:请求的url地址
// 参数3: 请求是同步还是异步。true为异步,默认为true

③ 发送请求 

xhr.send();

 ④ ⑤ 监听事件-->处理响应

 xhr.onreadystatechange = function () {
   // onreadystatechange 可以监听如下状态:
   //0:请求未初始化    1:服务器连接已经建立   2:请求已接收  3:请求处理中   4:请求已完成,且响应已就绪
        //判断当前状态是否已经响应完毕,处理响应
        if(xhr.readyState ==4){
            // 排除访问可能出现的问题,通过服务器返回的状态码来排除,304代表访问缓存
            if (xhr.status >=200 && xhr.status <300 ||xhr.status==304){
                console.log("请求成功!");
            }
            else {
                console.log("请求失败!");
            }
        }
    }


三、处理ie 发送ajax的兼容问题


由于ie低版本浏览器中没有XMLHttpRequest对象,而是ActiveXObject对象
处理方式:
//处理兼容问题
        var xhr;
        if(window.XMLHttpRequest){
            xhr =new XMLHttpRequest();
        }
        else {
            xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }


四、封装ajax的 get请求 (初级)


/*传参的格式 封装 将传入的对象,转为url 拼接的方式*/
function json2Str(data) {
           //定义数组
           var arr = [];
           //遍历传入的对象
           for (var key in data){
               //将json转为数组
               arr.push(key+'='+data[key]);
               console.log(arr);
           }
           //将数组转为固定格式的字符串
         return  arr.join('&'); //取出数组中的每一项,然后用&符号连接
       }
   function ajaxGet(url,data,success,error) {
             //封装get请求
             var xhr;
             if (XMLHttpRequest){
                 xhr = new XMLHttpRequest();
             }
             else {
                 xhr = new ActiveXObject("Microsoft.XMLHTTP");
             }
             xhr.open("get",url+'?'+data,true);
             xhr.send();
             xhr.onreadystatechange = function () {
                 if (xhr.readyState ==4){
                     if (xhr.status >=200 && xhr.status <300 ||xhr.status ==304){
                         success(xhr.response);
                     }
                     else {
                         error(xhr.status);
                     }
                 }
             }
         }
   ajaxGet('01-get.php',json2Str(data),function (res) {
             console.log(res);
         },function (code) {
             console.log("请求失败" + code);
         })


五、封装ajax的 get请求 (进阶)

处理ie中缓存和编码问题,
   ① 在ie浏览器下,如果发送一个相同url请求,它会通过本地缓存获取数据,即只有一个结果,不能获取到最新的数据
   ② 在ie中只能出现英文、数字、字母、下划线、ASIIC码,不能出现中文,韩文....它不会自动的进行编码,所有需要手动的编码
处理方案,对传入的参数进一步的进行处理
   ① 给传入的url添加一个随机因子,也可以通过加入时间戳的方式,这样不会出现相同的url请求
   ② 对传入的参数可能出现中文的地方进行 encodeURL编码

function json2Str(data) {
           //添加一个随机因子, 处理方式也可以是添加时间戳
           data.r = Math.random();
           //定义数组
           var arr = [];
           //遍历传入的对象
           for (var key in data){
               //将json转为数组
               arr.push(key+'='+encodeURI(data[key]));
               console.log(arr);
           }
           //将数组转为固定格式的字符串
         return  arr.join('&'); //取出数组中的每一项,然后用&符号连接
       }



六、封装ajax的 post请求的步骤


 //1 创建异步请求对象
    var xhr;
    if(XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }
    else {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    //2 设置url
    xhr.open('post','post.php',true);
    // 设置请求头,请求头的位置要放在open 和 send之间
    xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded');
    //3 发送请求
    xhr.send("name=zhang&age=12");
    //4 监听响应 -->处理响应数据
    xhr.onreadystatechange = function () {
        if (xhr.readyState ==4){
            if (xhr.status >=200 && xhr.status <300 || xhr.status==304){
                console.log(xhr.responseText);
            }
            else {
                console.log(xhr.status);
            }
        }
    }

post请求的注意点:

   ①  不是拼接到url中,参数必须通过send方 法传给服务器
   ②  设置请求头,请求头在open 和 send之间,这个位置是固定的  xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded');

七、封装ajax的 ajax请求(包括post 和 get)

  //封装的ajax请求方法
    function ajax(type,url,data,timeout,success,error) {
        var xhr;
        if(XMLHttpRequest){
            xhr = new XMLHttpRequest();
        }
        else {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        //处理参数
        var str =json2Str(data);
        //2 设置url
        if (type =='get'){
            xhr.open(type,url+'?'+str);
            xhr.send();
        }
        else {
            xhr.open('post',url,true);
            // 设置请求头,请求头的位置要放在open 和 send之间
            xhr.setRequestHeader("Content-type",'application/x-www-form-urlencoded');
            //3 发送请求
            xhr.send(str);
        }

        //4 监听响应 –>处理响应数据
        xhr.onreadystatechange = function () {
            if (xhr.readyState ==4){
                clearTimeout(timer);
                if (xhr.status >=200 && xhr.status <300 || xhr.status==304){
                    success(xhr.responseText);
                }
                else {
                    error(xhr.status);
                }
            }
        }
        //超时处理
        if(timeout){
            var timer = setTimeout(function () {
                alert("请求超时");
                xhr.abort();//中断请求
            },timeout)
        }
    }
    // 参入数据包装
    function json2Str(data) {
        //添加一个随机因子, 处理方式也可以是添加时间戳
        data.r = Math.random();
        //定义数组
        var arr = [];
        //遍历传入的对象
        for (var key in data){
            //将json转为数组
            arr.push(key+'='+encodeURI(data[key]));
            console.log(arr);
        }
        //将数组转为固定格式的字符串
        return  arr.join('&'); //取出数组中的每一项,然后用&符号连接
    }
    var data = {
        "name":'zhang',
        "age":21
    }
    //发送一个 ajax请求
   ajax('post','01-get.php',data,2000,function (res) {
       console.log(res);
   },function (e) {
       console.log(e);
   })


此处封装两大改动:
      ①  将 post 和 get请求封装在一起,通过type 参数来指定类型
      ②  设置了请求的延时,当网络不好的情况下,不然用户一直等下去,采用的是定时器来设置的
    

问题:
通过这种方式,已经可以实现基本的ajax请求,但是它仍然存在很多缺陷:
    ①  使用这个方法的时候,我需要看封装的方法,这样才能知道要传入几个参数,而且参入参数的位置是什么,这样十分的不利于提高效率
    ②  容错性差,有的参数是必须传的参数,而有的参数可有可无,都没有对他们进行容错处理。

下面我们再一次封装这个方法来解决存在的这两个问题


八、封装ajax的 ajax请求(终极)

 function json2str(json) {
        // 0.给json添加随机因子
        json.t = Math.random();
        // 1.将json转换为数组
        var arr = [];
        for(var key in json){
            arr.push(key+"="+encodeURIComponent(json[key]));
        }
        // 2.将数组转换为字符串返回
        return arr.join("&");
    }
    function ajax(options) {
        // 1.判断有没有传递option
        options = options || {};
        // 2.判断有没有url
        if(!options.url){  //没传入url
            return ;
        }
        // 3.设置默认值
        options.type = options.type || "get";
        options.timeout = options.timeout || 0;
        options.data = options.data || {};

        // 4.将参数转换为固定格式字符串
        var str = json2str(options.data);

        // 1.创建异步对象
        if(window.XMLHttpRequest){
            var xhr = new XMLHttpRequest()
        }else{
            var xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }

        if(options.type == "get"){
            // 2.设置URL
            xhr.open(options.type, options.url+"?"+str, true);
            // 3.发送请求
            xhr.send();
        }else{
            // 2.设置URL
            xhr.open(options.type, options.url, true);

            // 设置请求头
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

            // 3.发送请求
            xhr.send(str);
        }
        // 4.注册事件
        xhr.onreadystatechange = function () {
            // 5.处理返回数据
            // 判断请求状态
            if(xhr.readyState == 4){
                clearTimeout(timer);
                // 判断HTTP状态
                if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
                    options.success(xhr.responseText);
                }else{
                    options.error(xhr.status);
                }
            }
        }
        // 6.超时处理
        if(options.timeout){
            var timer = setTimeout(function () {
                xhr.abort(); // 中断请求
            }, options.timeout);
        }

    }
    //调用 ajax发送请求
    ajax({
        "type":"post",
        "url":'01-get.php',
        "data":{
           "name":"zhangsan",
            "age":21
        },
        "timeout":0,
        "success":function (res) {
            console.log(res);
        },
        "error":function (e) {
            console.log(e);
        }
    });

哈哈,花了几个小时,希望对大家有帮助!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章