美文网首页web基础学习之路
第十周第二天笔记

第十周第二天笔记

作者: 果木山 | 来源:发表于2018-10-01 22:56 被阅读0次

1 jsonp

1.1 script预解释

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

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后面的函数,给函数传入一个实参数据;
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <title>jsonp体验</title>
     </head>
     <body>
     <script>
         window["xhfd"]=function(data) {
             console.log(data);
         }
     </script>
     <!--请求步骤:在url这个请求地址中,通过wd后面的赋值来进行查找,查找到的数据作为实参传入到cb后面的函数中执行-->
     <script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=zhouxingchi&cb=xhfd"></script>
     </body>
     </html>
    

2 ajax封装

  • jQuery中ajax体验
    • 注意:在百度服务器中搜索获取地址后,向一个函数中传入实参数据,执行函数,必须设置jsonp参数为cb,cb设置的函数名为默认的jQuery...;
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <title>jQuery中jsonp体验</title>
     </head>
     <body>
     <script src="jquery.js"></script>
     <script>
         //https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=zhouxingchi&cb=xxx
         //分析:问号之前的为请求地址;wd等号后为搜索的内容;cd后面为调用函数的函数名;
         $.ajax({
             url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",//请求地址;后台接口
             data:{"wd":"扶摇"},//前端传给后台的数据,可有可无的;
             type:"get",//请求方式,post,get,jsonp可有可无,如果写了jsonp,没写默认的都是get;
             dataType: "jsonp",//返回的数据类型,可有可无的,如果传了,拿到的数据就是josn对象,如果没有,拿到的是字符串
             jsonp:"cb",//可有可无,没有,默认是callback;但在百度服务器中搜索必须设置为cb
             fnLoading:function(){//等待加载
                 console.log("数据正在加载中,请耐心等待");
             },
             complete:function(){//加载完成
                 console.log("数据请求结束")
             },
             success:function(data){//数据请求成功
                 console.log(data);
             },
             error:function (data) {//数据请求失败
                 //数据请求失败的处理;
             },
             timeout:2000//请求超时,可有可无,没传默认3000;
         })
     </script>
     </body>
     </html>
    
  • 封装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请求;
    • 代码:
      • 执行代码:
       <!DOCTYPE html>
       <html lang="en">
       <head>
           <meta charset="UTF-8">
           <title>封装的ajax</title>
       </head>
       <body>
       <script src="JS/ajax.js"></script>
       <script>
           myAjax({
               url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",
               data:{wd:"zhouxingchi"},
               type:"jsonp",
               dataType:"json",
               jsonp:"cb",//此处必须设置jsonp为cb,才能使用
               success:function (data) {
                   console.log(data);
               }
           });
       </script>
       </body>
       </html>
      
      • 封装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的属性

相关文章

  • 英文读物《绿野仙踪》2/100读书打卡

    读书已经开始第十六天打卡,笔记更新到第二天,就当复习啦!

  • 第十周第二天笔记

    1 jsonp 1.1 script预解释 基础知识:每一个script指的就是一个独立的域,不同的script代...

  • 2014301020155

    第九周作业:第九周作业 第十周作业:第十周作业 第十一周作业:第十一周作业 第十三周作业:第十三周作业 第十四周作...

  • 2019周总结|第二周周总结:我的“6+4”小生活

    2019.3.9 第十周 2019,第10周第6天, 三月的第2周第二天, 2019倒计时297天。 不知不觉,感...

  • 山东宇悦妈读经记录

    日期:2018年11月30日 周期:第五周第二天 读经内容: 1.《周易•上经•泰卦第十一—同人卦第十三》 名句语...

  • 第七周到第十三周复习笔记

    第七周到第十三周知识复习笔记 第七周 JS盒子模型client类offset类scroll类 字符串search(...

  • 山东宇悦妈读经记录

    日期:2018年12月9日 周期:第六周第二天 读经内容: 1.《周易•上经•大有卦第十四—豫卦第十六》 名句语录...

  • 2018-05-12

    2018年开学第十周第二天 2017年5月8日 星期二 多云 妈妈和宝贝系统读经第147周第2...

  • 妈妈和宝贝系统诵读国学经典成长自己

    开学第十周第二天 2017年10月31日 星期二 多云 妈妈和宝贝系统读经第121周第2天,累积849天...

  • 做好自己

    开学第十五周第二天 2017年12月5日 星期二 多云 妈妈和宝贝系统读经第126周第2天,累积884天 ...

网友评论

    本文标题:第十周第二天笔记

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