第十周第二天笔记

1 jsonp

1.1 script预解释

  • 基础知识:
    • 每一个script指的就是一个独立的域,不同的script代表不同的域;
    • 两个不同的域之间函数的调用,必须使函数定义阶段的域先引入,然后函数调用的函数的域后引入;顺序相反不能拿到数据;
     //1. 函数定义阶段的域先引入,函数执行阶段的域后引入,此时执行正确,弹出123;
     
     
     
     
    
     //2. 函数执行阶段的域先引入,函数定义阶段的域后引入,此时执行会报错,即:fn is not defined;
     
     
     
     
    

1.2 jsonp原理

  • jsonp原理体验:
    • jsonp的原理:通过一个script建立一个独立的域,这个域的请求地址为百度的一个服务器,通过wd的值来查找数据,然后去将数据作为一个实参,传入到cb后面的函数中,执行cb后面函数名的函数;
    • jsonp请求的实质是获取百度服务器中数据库中的数据,作为实参传入到全局函数中;获取数据的方式:在百度所搜框中输入文字后,在控制台中的network中会生成数据,然后找到带su?wd=的地址后,在新的页面中打开,就会看到数据;然后删除没用的地址数据;设置cb的值为全局函数名即可;
    • jsonp请求的三步:
      1. 定义一个有名字的全局函数,作为cd后面的函数名;
      2. 在全局函数中设置形参,获取实参数据;
      3. 通过script发送请求:通过script来创建一个域,src赋值中包括(url?参数&cb=函数名),在域中,执行cb后面的函数,给函数传入一个实参数据;
     
     
     
         
         jsonp体验
     
     
     
     
     
     
     
    

2 ajax封装

  • jQuery中ajax体验
    • 注意:在百度服务器中搜索获取地址后,向一个函数中传入实参数据,执行函数,必须设置jsonp参数为cb,cb设置的函数名为默认的jQuery...;
     
     
     
         
         jQuery中jsonp体验
     
     
     
     
     
     
    
  • 封装myAjax函数
    • 参数:ajax({url:xxx,data:xxx,type:xxx,dataType:xxx,jsonp:xxx,fnLoading:xxx,complete:xxx,success:xxx,error:xxx,timeout});
    • 思路:
      • 获取参数;
      • 获取数据的四步
        1. 创建一个xml对象:需注意的是IE6浏览器下不兼容,需要做兼容处理
        2. 打开地址
        3. 发送请求
          • 通过switch来创建不同情况下的设置
          • get请求:参数在地址中,在url?的后面,以键值对的形式连接;
          • post请求:参数在请求体中,地址url后面不跟参数;
          • jsonp请求:与get和post两种形式不同,独立设置
        • jsonp请求的步骤
          • 新建一个全局变量,作为函数名,注意函数名中不能存在小数点;
          • 创建一个全局函数,函数中设置形参,用于获取实参;
          • 新建一个script标签,插入到body的最后面,用于发送请求,其中src值的形式为:url?参数&cb=函数名
        1. 响应请求
          • 响应请求前可以添加fnLoading函数;
          • 添加请求事件后判断xml.readyState===4成立后,代表请求成功,可以设置执行complete函数;
          • 通过正则校验xml.status的状态码是否为2xx
            • 如果校验成功,代表响应成功,执行success函数;执行函数前,判断需要返回的类型,然后传入响应的实参给函数;
            • 如果校验失败,则返回状态码给error函数;
      • 添加等待超时判断
        • 添加定时器,判断在指定timeout时间内,是否响应成功,如果未成功,执行定时器函数,弹出信息;
        • 注:在定时器前面判断是否为jsonp执行,如果是的话,阻断程序执行,不执行定时器;
    • 注意:
      • 使用时,设置对象中的属性data时,用对象的形式设置;利用json2url函数,将对象转换为字符串格式为"key=val&key=val"形式;
      • 封装的get和post只能在本地获取数据,不能跨域获取;跨域获取用jsonp请求;
    • 代码:
      • 执行代码:
       
       
       
           
           封装的ajax
       
       
       
       
       
       
      
      • 封装JS代码:
       //参数:ajax({url:xxx,data:xxx,type:xxx,dataType:xxx,jsonp:xxx,fnLoading:xxx,complete:xxx,success:xxx,error:xxx,timeout})
       //将对象中的属性名和属性值转化为key=val&key=val的形式
       function json2url(obj) {
           //参数:对象,返回值:字符串
           //思路:对象-数组-字符串
           obj.t=Math.random();//避免缓存
           var ary=[];
           //遍历对象
           for(var attr in obj){
               ary.push(attr+"="+obj[attr]);
           }
           return ary.join("&");
       }
       function jsonParse(strJson) {
           return "JSON" in window?JSON.parse(strJson):eval("("+strJson+")");
       }
       function myAjax(json) {
           json=json||{};
           //如果json中请求地址url不存在
           if(!json.url) return;
           //参数获取
           var url=json.url;
           //data属性值为一个对象,对象中为参数
           var data=json.data||{};
           var type=json.type||"get";
           var jsonp=json.jsonp||"callback";
           var timeout=json.timeout||3000;
           var timer=null;
           //四步:
           //1 创建一个xml对象
           //每个类函数都是window的一个属性;
           if(window.XMLHttpRequest){
               var xml=new XMLHttpRequest();
           }else{//IE6兼容处理
               var xml=new ActiveXObject("Microsoft.XMLHTTP");
           }
           //2 打开地址;3 发送请求
           //get请求:参数在地址中,在url?的后面,以键值对的形式连接;
           //post请求:参数在请求体中,地址url后面不跟参数;
           switch(type.toLowerCase()){
               case "get":
                   xml.open("get",url+"?"+json2url(data),true);
                   xml.send(null);
                   break;
               case "post":
                   xml.open("post",url,true);
                   xml.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                   xml.send(json2url(data));
                   break;
               case "jsonp":
                   //新建一个全局函数
                   var kbfd="jsonp_"+Math.random();
                   kbfd=kbfd.replace(".","");//函数名中不能存在小数点,所以需要替换
                   window[kbfd]=function (data) {
                       json.success && json.success(data);
                       //卸磨杀驴,干掉script
                       document.body.removeChild(oS);
                       //将oS赋值为null;
                       oS=null;
                   };
                   data[jsonp]=kbfd;
                   //创建script标签,设置其src,通过script发送请求
                   var oS=document.createElement("script");
                   //script中src包含url?参数&cb=kbfd
                   oS.src=url+"?"+json2url(data);
                   //script必须插入到页面的底部
                   document.body.appendChild(oS);
                   break;
           }
           //响应请求之前的准备
           json.fnLoading && json.fnLoading();
           //4 响应请求
           xml.onreadystatechange=function () {
               if(xml.readyState===4){
                   //请求成功
                   json.complete && json.complete();
                   clearTimeout(timer);
                   //判断后台响应成功还是失败;
                   if(/^2\d{2}$/.test(xml.status)){//响应成功
                       if(json.dataType==="json"){
                           json.success && json.success(jsonParse(xml.responseText));
                       }else{
                           json.success && json.success(xml.responseText);
                       }
                   }else{//响应失败
                           json.error && json.error(xml.status);
                   }
               }
       
           };
           if(type==="jsonp") return;
           //5 等待超时
           timer=setTimeout(function () {
               alert("您的网络不行啊");
               xml.onreadystatechange=null;
           },timeout);
       }
      
  • 知识点
    • 类是window的属性

你可能感兴趣的:(第十周第二天笔记)