处理封装AJAX的GET请求遇到的问题

1,264 阅读1分钟

前言

经过上文,我们已经了解了AJAX,下面来封装GET请求

Ajax的GET请求封装

function ajax(url,obj,success,error){
    // 	0.将对象转换成字符串
    var str = objToString(obj); //obj就是为了将url和传递的数据分开,可以把它当成一个对象,在传递的过程中,将obj变成对应的字符串拼接到url的后面。这样数据也传进去了。另外为了兼容IE,可以在obj转换的过程中加个obj.t = new Date().getTime();
    // 	1.创建一个异步对象xmlhttp;
    var xmlhttp; 
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
    } else{// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    }
    // 	2.设置请求方式和请求地址;	
        //xmlhttp.open("GET",url,true);
        xmlhttp.open("GET",url+"?t=" +str;	
    // 	3.发送请求;
            xmlhttp.send();
    // 	4.监听状态的变化;
    xmlhttp.onreadystatechange = function(){
        if (xmlhttp.readyState === 4) {
            if (xmlhttp.status >= 200 && xmlhttp.status < 300 || xmlhttp.status == 304) {
                // 	5.处理返回的结果;
                success(xmlhttp);//成功后回调;
            }else{
                error(xmlhttp);//失败后回调;
            }					
        }
    }
}
function objToString(obj){
  obj.t = new Date().getTime();
  var res =[];
  for(var key in obj){
    res.push(key + " = " +obj.[key]);
  }
  return res.join("&");
}

注意

  1. IE中的兼容问题
  2. 我们传递url的时候需要传递我们添加的数据,但是那样写不太好,我们可以加传递一个参数obj,这个obj就是为了将url和传递的数据分开,可以把它当成一个对象,在传递的过程中,将obj变成对应的字符串拼接到url的后面。这样数据也传进去了。另外为了兼容IE,可以在obj转换的过程中加个obj.t = new Date().getTime();

其他问题处理

当前我们封装的ajax方法还有两个细节需要处理一下:

  1. 当我们利用我们的ajax放的发送一个请求到远处服务器时,我们需要等待远程服务器去响应我们的请求,等待远程服务器将响应的结果返回给我们,但是这个响应的速度是不确定的,因为响应的速度是由本地网络和远程服务器的网速等共同决定的,所以我们不可能一直等待服务器的响应。那么这里我们需要新增另外一个功能:设置超时时间的功能,即告诉它我的请求会等待多长的时间,如果这么长的时间内都没有响应我们发送的请求,那我就在这里自动的终止这次请求;
function ajax(url,obj,timeout,success,error){
    //  0.将对象转换成字符串
    var str = objToString(obj); 
    //  1.创建一个异步对象xmlhttp;
    var xmlhttp,timer; 
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
    } else{// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    }
    //  2.设置请求方式和请求地址;  
        //xmlhttp.open("GET",url,true);
        xmlhttp.open("GET",url+"?t=" +str;  
    //  3.发送请求;
        xmlhttp.send();
    //  4.监听状态的变化;
    xmlhttp.onreadystatechange = function(){
            clearInterval(timer);
        if (xmlhttp.readyState === 4) {
            if (xmlhttp.status >= 200 && xmlhttp.status < 300 || xmlhttp.status == 304) {
                //  5.处理返回的结果;
                success(xmlhttp);//成功后回调;
            }else{
                error(xmlhttp);//失败后回调;
            }                   
        }
    }
    }
    function objToString(obj){
      obj.t = new Date().getTime();
      var res =[];
      for(var key in obj){
        res.push(key + " = " +obj.[key]);
      }
      return res.join("&");
    }
    //判断外界是否传入了超时时间
    if(timeout){
            timer = setInterval(function(){
                    xmlhttp.abort();//中断请求
                    clearInterval(timer);
            },timeout);
    }
  1. 上面的情况还有一个问题,在我们发送一个请求的时候,我们的URL当中是不能出现中文的。 我们在百度上面搜索关键字时,如张三,通常会看到地址栏那里是:https://www.baidu.com/s?wd=张三;但是我们如果复制到编辑器,会变成https://www.baidu.com/s?wd=%E5%BC%AO%E4%B8%90这样的。其实在它提交请求的时候,并不是中文的张三,而是用%E5%BC%AO%E4%B8%90这段字符表示张三。而张三这个中文是浏览器显示给你的,真正提交的是%E5%BC%AO%E4%B8%90这段字符串。

那么我们需要在专门处理obj的函数里面,将中文处理了在传入服务器。

需要将key和value转成非中文的形式,因为url不能有中文。使用encodeURIComponent()转码;URL中只能出现字母 数字 下划线和ASCII码

完善如下:

function ajax(url,obj,timeout,success,error){
    //  0.将对象转换成字符串
    var str = objToString(obj); 
    //  1.创建一个异步对象xmlhttp;
    var xmlhttp,timer; 
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari 
      xmlhttp=new XMLHttpRequest(); 
    } else{// code for IE6, IE5 
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    }
    //  2.设置请求方式和请求地址;  
        //xmlhttp.open("GET",url,true);
        xmlhttp.open("GET",url+"?t=" +str;  
    //  3.发送请求;
        xmlhttp.send();
    //  4.监听状态的变化;
    xmlhttp.onreadystatechange = function(){
            clearInterval(timer);
        if (xmlhttp.readyState === 4) {
            if (xmlhttp.status >= 200 && xmlhttp.status < 300 || xmlhttp.status == 304) {
                //  5.处理返回的结果;
                success(xmlhttp);//成功后回调;
            }else{
                error(xmlhttp);//失败后回调;
            }                   
        }
    }
    }
    function objToString(obj){
      obj.t = new Date().getTime();
      var res =[];
      for(var key in obj){
            //需要将key和value转成非中文的形式,因为url不能有中文。使用encodeURIComponent()转码;URL中只能出现字母 数字 下划线和ASCII码
        res.push(encodeURIConponent(key) + " = " +encodeURIConponent(obj.[key]));
      }
      return res.join("&");
    }

    //判断外界是否传入了超时时间
    if(timeout){
            timer = setInterval(function(){
                    xmlhttp.abort();//中断请求
                    clearInterval(timer);
            },timeout);
    }
}