第十周第二天笔记

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的属性
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,474评论 1 45
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,392评论 1 92
  • 第一章 入门 基本功能:访问和操作 dom 元素,控制页面样式,对页面的事件处理,与ajax完美结合,有丰富的插件...
    X_Arts阅读 1,045评论 0 2
  • 亲爱的自己: 30岁了呢,今天你开心吗,你在做什么,你喜欢现在的生活吗?有没有人在你身边。 我在23岁的今天写信给...
    我家楼下阅读 264评论 0 0
  • 人有三种驱动力,第一种是生存需要,是一种动物的本能;第二种是奖励/惩罚,这是一种简单的用金钱、物质来刺激的驱动方式...
    荒原苍狼阅读 187评论 0 0