ajax+jsonp库的封装

作者: icessun | 来源:发表于2017-08-01 21:50 被阅读243次

    jsonp

    @(我的第一个笔记本)

    • 取数据:控制台----network----wd(关键词)-----cb(json格式数据返回时前面的函数名)

    • script:可以跨域 ,是一个作用域

    jsonp原理

    三部曲:

    • 定义了有名字的全局函数
    • 通过script发生请求,请求必须在全局函数之后,因为要使用的东西必须在使用之前调用,预解释
    • 当全局函数被调用的时候,会自动传入一个实参,就是请求的数据,在全局函数里面通过形参来接收这是实参传递的数据
    • 根据上面的取数据的过程,我们可以

      • 定义一个全局函数(名字和cb后面的名字一样),接收参数,要搜索的,里面存放请求返回的json格式的数据
      • 那个cb,也就是函数名的调用,当通过一个script发起一个跨域请求的时候,就相当于调用了定义的全局函数,然后全局函数接收跨域请求传过来的参数(数据),最后取得返回的数据
    • 传统的ajax是不能跨域请求的,要通过jsonp

    封装ajax+jsonp库

    ajax库使用时的设计

    // jquery里面的ajax传入一个对象,不用记住参数的位置,只需要传入一个对象就行
    ajax({
        url: "test.php",// 请求地址
        data: {'wd':'icessun'},// 前端传递给后台的数据,请求参数,最后使用对象传递
        type: 'jsonp',//请求方式,(get(获取数据,显示在地址栏里面),post(提交数据,显示在请求体里面),jsonp)
        jsonp: 'cb',// 回调函数的名字,jquery中默认是callback
        dataType: 'json',// 返回数据类型
        success:function(data){
             console.log(data);
         },// 数据请求成功
         error:function(){
          
          },// 数据请求失败
          complete:function(){
           
           },// 加载完成,数据请求结束
           fnLoading:function(){
            
            },// 等待加载,数据正在加载中
            timeout:function(){
             
             },// 请求超时
     })
    

    定义一个全局的ajax函数,按照上述设计使用

    • 所有的类都是window的全局属性,故可以使用window.XMLHttpRequest来验证浏览器的高低,兼容浏览器
    • 表单序列化:$('form').serialize():把表单里面的数据拼接成key=value的方式传递
    • 表单enctype:请求响应数据的方式
    • 数组转字符串:join;字符串转数组:splite
    // json2url  json格式数据转字符串  key=value形式的字符串
    function json2url(json){
        // 避免缓存
        json.t=Math.random();
        var ary=[];
        // 遍历对象
        for(var attr in json){
            ary.push(attr+'='+json[attr]);
         }
        return  ary.join('&'); // 使用&拼接起来的字符串
     }
    
    // 字符串转为json格式数据
    function jsonParse(jsonStr){
        return 'JSON' in window? JSON.parse(jsonStr):eval('('+jsonStr+')');
     }
    
    
    // 考虑有几个参数 
    function ajax(opt){
       // 传入了参数就接收,没有传就是空对象
       opt=opt||{}; // 最多undefined
       if(!opt.url) return;  // 没有请求地址,直接阻断执行
        
        // 默认值的设置
        var data=opt.data||{};
        var tyep=opt.type||{};
        var jsonp=opt.jsonp||'callback';
        var timeout=opt.timeout||3000; 
        var timer=null;
    
    
     // ajax封装的四部曲
          // 1 创建一个xml对象  判断浏览器是否支持XMLHttpRequest
           if(window.XMLHttpRequest){
               var xml=new XMLHttpRequest();
            }else{
                var xml=new ActiveXObject('Microsoft.XMLHTTP');
             }
          // 2 打开地址  考虑请求方式GET(打开的地址里面包含参数) POST(参数在请求体里面) JSONP 参数的传递方向不一样
         // 3 发送请求
             switch(type.toLowerCase()){
                 // toLowerCase()  严格比较 ===
                 case 'get': // 请求参数在地址栏
                 // get 请求 参数放在url里面传递
                    xml.open('get',opt.url+'?'+json2url(data),true);// true异步
                    xml.send(null);
                       break;
                 case 'post':  // 请求参数在请求体
                 // post 请求,就相当于一个人,有头有体
                     xml.open('post',opt.url,true);
                     xml.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); // 设置请求头
                     xml.sned(json2url(data)); // 发送参数 请求体
                       break;
                 case 'jsonp':
                 // 创建一个有名的全局函数,名字里面不能有点  坑
                     var fnName='jsonp_'+Math.random();
                     fnName=fnName.replace('.','');
                 // 创建一个script 可以对本页面发起jsonp请求 data是一个对象
                      data[jsonp]=fnName; // 把fnName插入到data传递的参数里面
                      var oS=document.createElement('script');
                      oS.src=opt.url+'?'+json2url(data);  // 发送请求,然后这个全局函数被调用window[fnName]
                      document.body.appendChild(oS);
                 // 在全局函数( window[fnName])里面接收实参
                   window[fnName]=function(val){
                      opt.success&&opt.success(val);
                      // script是用来发生请求的,当请求完毕,使script为null
                      document.body.removeChild(oS);
                  };
                       break;
              }
    // 正在加载
         opt.fnLoading&&opt.fnLoading();
    
         // 4 响应请求  异步操作
         xml.onreadystatechange=function(){
              if(xml.readyState==4){
                   opt.complete&&opt.complete(); // 加载完成
       
                   clearTimeout(timer);
                   // 是否成功
                   if(/^2\d{2}$/.test(xml.status)){
                       if(opt.dataType==='json'){
               // 获取成功的数据,进行json格式的转变            opt.success&&opt.success(jsonParse(xml.reponseText));
                        }else{
                             json.success&&json.success(xml.reponseTest);
                         }
                    }else{
                          opt.error&&opt.error(xml.status);
                     }
               }
          }
    
    // jsonp立即调用 
    if(type === 'jsonp') return;
    
       // 等待超时,开启定时器
       timer=setTimout(function(){
          console.log('网络不行')
             xml.onreadystatechange=null; // 不等待请求
        },timeout)
       
     }
    

    相关文章

      网友评论

        本文标题:ajax+jsonp库的封装

        本文链接:https://www.haomeiwen.com/subject/ffuslxtx.html