JS闯关之路我们就爱程序媛

ajax+jsonp库的封装

2017-08-01  本文已影响243人  icessun

jsonp

@(我的第一个笔记本)

jsonp原理

三部曲:

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

封装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函数,按照上述设计使用

// 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)
   
 }
上一篇下一篇

猜你喜欢

热点阅读