zoukankan      html  css  js  c++  java
  • JavaScript的jsonp

     目录索引:

    一、AJAX的概念
    二、POST && GET
    三、原生实现AJAX简单示例

      3.1 实现代码
      3.2 重点说明
    四、框架隐藏域

      4.1 基本概念
      4.2 后台写入脚本
      4.3 JS主动判断Iframe的改变
      4.4 表单提交数据实战
    五、JQ 的 AJAX
      5.1 load()
      5.2 $.get()
      5.3 $.post()
      5.4 $.getScript()
      5.5 $.getJson()
      5.6 $.ajax()
        a. 常用的属性说明
        b. 常用的事件说明
        c. 全局事件说明
        d. $.ajaxSetup()
      5.7 AJAX的再次封装
      5.8 序列化表单
    六、JSONP的概念
      6.1 JSONP的概念
      6.2 自己封装的JSONP
      6.3 JQ的JSONP使用。

    一、AJAX的概念

    AJAX(Asynchronous JavaScript And XML) 中文翻译即“异步的JavaScript 和 XML”。
    AJAX实际上是对现有的多种技术进行整合使用得到的技术。它包括:
      1) XMLHttpRequset:浏览器的XMLHttpRequset对象,该对象用于向后台发送请求与接收响应。
      2) JavaScript : 用于接收、处理、显示XMLHttpRequest响应后的内容。
      3) XML : (Extensible Mrakup Language) 扩展的标记语言,它规定了一种统一的,可跨平台与系统的文本标记格式,而在AJAX中则用于前端与后台的数据格式定义,但实际上,现在已经很少会有人使用这种格式进行数据的传输,更多的是采用JSON数据格                   式,相比之下前者用于说明数据结构的冗余代码更多,但是是结构清晰。
    前面说过AJAX不是一种新的技术,而是对已有的技术进行整合得到的,其实AJAX的核心技术XMLHttpRequest是微软率先在IE5.0浏览器上实现的,只是那时候一值将该功能作为一个ActiveXObject的插件使用,在IE实现该功能后,其它的浏览器,如google、firefox等则以自己的方式也实现了该功能,但是这个功能并没有受到使用者的重视,一直到2005年谷歌在其旗下的Google Map和 Google Gmail等产品率先使用该技术,才让AJAX技术真正的流行开来。
    AJAX将的基本功能就是,当用户在前端页面发起请求后,这个请求会被XMLHttpRequest对象发送到后台,后台接收请求后进行处理,并将结果按照规定的数据格式,重新发送到前端,当前端页面接响应收到的结果数据后,则会使用JS对数据进行解析、处理、展示等。


    总之,AJAX技术的本质就是:实现页面无刷新数据动态更改。
    相比之前需要通过刷新页面或者跳转链接才能获得响应的数据,AJAX具有以下几点优势:
      + 无刷新的数据获取,提高用户的体验性。
      + 减轻服务器的带宽
      + 后台与前端的紧密耦合
    但是以上的优点,也会产生使用AJAX技术的缺点
      + 破坏浏览器的“前进”,“后退”按钮
      + 对搜索引擎的SEO支持不好。

     二、POST && GET

    POST 与 GET都是HTTP请求方式中的一种。而请求方式又决定了参数传输以及获取数据方式的不同。
    这里,我们只需要知道与了解POST 与 GET在应用层方面的差异即可。
      ·  GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给WEB服务器。
      ·  GET方式传输数据有大小限制(通常不能大于2KB),而POST上传输数据,理论上不受限制。
      ·  GET方式传输的数据会被浏览器缓存,因此使用GET方式传输账号,密码之类的,就会有很大的风险。
      ·  GET方式和POST方式传递的数据在服务器端的获取也不相同。在PHP中,GET方式的数据可以采用$_GET[]获取,而POST则是$_POST[]获取,但两种都可以使用$_REQUEST[]获取。

    三、原生实现AJAX简单示例

     3.1 实现代码

      ·  前端代码 ·

    复制代码
     1 function ajaxGetData(params){
     2 
     3     var xhr = null, //创建接受XMLHttpRequest对象变量
     4         method = params.method && params.method.toUpperCase() || 'POST',
     5         url = params.url || '',
     6         data = params.data || null,
     7         async = params.async || true, //异步还是同步,默认异步。
     8         callback = params.callback || function(){};
     9 
    10 
    11     if(window.XMLHttpRequest){    //解决XMLHttpRequest对象的兼容性
    12         xhr = new XMLHttpRequest();
    13     }else if(window.ActiveXObject){    //如果是IE6.0之前的,那么那么采用ActiveXObject对象。
    14         xhr = new ActiveXObject('Microsoft.XMLHTTP');
    15     }else{
    16         return false;    //如果浏览器不支持该功能, 那么就阻止程序运行。
    17     }
    18 
    19 
    20     if(method === 'POST'){
    21         xhr.open('POST',url,async); 
    22         xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//POST提交数据,专用头部
    23         xhr.send(data);    //发送请求,并附加数据,如果没有数据,则为默认值,null
    24     }
    25 
    26     if(method === 'GET'){
    27         (data)?'':data = '';
    28         xhr.open('GET',encodeURI(url+'?'+data),async);    //GET请求,通过URL附加数据传输。而通过编码,可以解决IE6/7在GET方式下传输中文参数出现乱码的情况。后台则可以通过 urldecode($_GET['a']) 进行解码
    29         xhr.send(null);
    30     }
    31 
    32     xhr.onreadystatechange=function(){    //注册请求的回调函数。
    33         if(xhr.readyState == 4 && xhr.status == 200){    //readyState 这个是请求的状态,4表示请求成功。 status表示响应应答或者数据传输的状态。200表示数据传输成功。
    34             callback(xhr);
    35         }
    36     }
    37 
    38 
    39 }
    复制代码

      · 后端代码 ·

    1 <?php
    2     $v1 = $_REQUEST['v1'];
    3     $v2 = $_REQUEST['v2'];
    4     echo ($v1+$v2);
    5 ?>

      · 调用方式 ·

    复制代码
     1 elem.onclick=function(){
     2     ajaxGetData({
     3         url:'index.php',
     4         method:'get',
     5         data:'v1=1&v2=2',
     6         async:true,
     7         callback:function(xhr){
     8             alert(xhr.responseText);
     9         }
    10     });
    11 };
    复制代码

     3.2 重点说明

    · ActiveXObject
      ActiveX插件可以与微软的其它组件进行交换,包括这里我需要的微软自带的HTTP请求方法。
      new ActiveXObjcet('Microsoft.XMLHTTP') IE5.0+ 支持的HTTP请求方法。

    · setRequestHeader
      该方法可以设置请求的头部信息,常用以post方式向一个动态网页文件提交数据时使用。这是因为PHP中的$_POST['key']方法,需要用到键值对的格式,因此必须声明请求的类型为: setRequestHeader('Content-Type','application/x-www-form-   urlencoded') 以表单提交数据的方式来发送数据到服务器。

    · readyState && status
      readyState表示HTTP请求的运行状态,不论请求的数据是否找到,都会经历以下的过程:
        0 ---- 请求初始化,简历xhr对象。
        1 ---- 与服务器建立连接,open()方法已经成功调用。
        2 ---- 请求已经接收
        3 ---- 请求正在处理
        4 ---- 请求处理完成

       status 则表示了HTTP所请求数据的状态[常见的反馈码]:

        200 ---- 数据请求完成,已经可以使用。
        404 ---- 页面未找到。

    · open

       功能:初始化请求的参数。
       格式:open('请求数据的方式','所要请求的页面URL','是否异步');
       说明:
          · 请求数据的方式:GET | POST
          · 是否异步:true(异步) | false(同步)
       * 如果存在setRequestHeader()方法,一定要把open()方法放在它之前的一行。

    . send
       功能:发送请求。
       格式:send(params)
       代码示例:
        send(null)
        //在GET方式下用这种方式,因为参数会在open方法中附加在URL后进行传输。

      send('fname=神&lname=经病') 
        //在POST方式,用这种方式传输参数,但要记得使用setRequestHeader()方法。

    . 同步与异步
       xmlHttpReq对象的open()方法第三个参数可以设置同步或异步的方式。
          true - 表示为异步,它不会等待服务器的执行完成。
         false - 表示同步,它会等待服务器执行完成,否则便会挂起程序,一直等待,一般不推荐是用同步的方式,不过对于一些小程序还是可以使用的。

    · 使用时间戳或随机数来确保无缓存的请求数据
      //时间戳
       open('GET','index.php?t='+ new Date()*1,true); 

      //随机数
       open('GET','index.php?m='+ Math.random(),true); 

    四、框架隐藏域

     4.1 基本概念

    “框架隐藏域” 技术,现在主要用于文件上传时使用,因为AJAX技术,无法实现文件的上传。
      在AJAX技术提出之前,如果想实现无刷新的提交或改变数据,一般都是通过“框架隐藏域”来实现的。
    “框架隐藏域”的基本思路就是:页面会有一个空白的Iframe,通过display:none进行隐藏,然后在数据需要改变时,通过指定iframe的src值,让其跳转到所要请求的页面。然后将值传输到后台,那么页面的刷新,也会在隐藏的iframe中进行,当前窗口页面并不会被刷新。最后父页面在去获取隐藏的iframe中的结果即可,这样,便实现了通过隐藏iframe方式来实现无刷新的数据提交或改变。

    一般来说,通过iframe实现无刷新,主要有以下几种方法:

      将值作为url参数附加到iframe的src中。
      在iframe中放入一个表单,然后让iframe中的表单进行提交
      将父页面的表单元素的target值指定为iframe的name值。

    而父页面获取隐藏iframe请求结果的方法,有以下几种:

      + 通过onload,或JQ的load方法读取改变后的iframe的值,切记一点是,onload事件一定要在iframe发生改变之前就要绑定。
      + 后台的结果是一段JavaScript代码,改代码会回调父页面的指定方法,并传输请求结果:
         echo '<script>callback('数据提交成功')</script>' 

       4.2 后台写入脚本

      · 前端代码 ·

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5 </head>
     6 <body>
     7     <button>click</button>
     8     <iframe id="ifr" src="" style="display:none" frameborder="0"></iframe>
     9 </body>
    10 </html>
    11 <script>
    12     var btn = document.getElementsByTagName('button')[0],
    13         ifr = document.getElementById('ifr');
    14     btn.onclick=function(){
    15         ifr.src="index.php?v=success?"+new Date().getTime(); //加入时间戳
    16     }
    17 </script>
    复制代码

      · 后端代码 ·

    1 <?php
    2     $v = $_REQUEST['v'];
    3     echo '<script>alert("'.$v.'")</script>';
    4 ?>

      

       4.3 JS主动判断Iframe的改变

      · 前端代码 ·

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5 </head>
     6 <body>
     7     <button>click</button>
     8     <iframe id="ifr" src="" style="display:none" frameborder="0"></iframe>
     9 </body>
    10 </html>
    11     <script>
    12         var btn = document.getElementsByTagName('button')[0],
    13             ifr = document.getElementById('ifr');
    14         
    15         function load(obj,fn){
    16 
    17            obj.isloaded = false;
    18            obj.onreadystatechange=function(){
    19                 if(this.readyState == 'complete'){
    20                     if(!this.isloaded){
    21                         this.isloaded = true;
    22                         fn && fn();
    23                     }
    24                 }
    25             };
    26             obj.onload=function(){
    27                if(!this.isloaded){
    28                    this.isloaded = true;
    29                    fn && fn();
    30                }
    31             };
    32 
    33         }
    34 
    35         btn.onclick=function(){
    36             
    37             load(ifr,function(){alert(ifr.contentWindow.document.body.innerHTML)});
    38             ifr.src='index.php?'+new Date().getTime()+'&v=success';
    39         
    40         };
    41 
    42 </script>
    复制代码

      · 后端代码 ·

    1 <?php
    2     $v = $_REQUEST['v'];
    3     sleep(5);
    4     echo 'success';
    5 ?>

       4.4 表单提交数据实战

      · 前端代码 ·

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5 </head>
     6 <body>
     7     <form action="index.php"  method="post" target="MyIframe">
     8         <input type="text" name="v" />
     9         <input type="button" id="btn" value="SubMit" />
    10     </form>
    11     <iframe id="ifr" style="display:none" frameborder="0" name="MyIframe"></iframe>
    12 </body>
    13 </html>
    14 <script>
    15     var btn = document.getElementById('btn'),
    16         ifr = document.getElementById('ifr');
    17     
    18     function load(obj,fn){
    19 
    20        obj.isOpen = false;
    21        obj.onreadystatechange=function(){
    22             if(this.readyState == 'complete'){
    23                 if(!this.isOpen){
    24                     this.isOpen = true;
    25                     fn &&  fn();
    26                 }
    27             }
    28         };
    29         obj.onload=function(){
    30            if(!this.isOpen){
    31                this.isOpen = true;
    32                fn && fn();
    33            }
    34         };
    35 
    36     }
    37 
    38     btn.onclick=function(){
    39         document.forms[0].submit();
    40         load(ifr,function(){alert(ifr.contentWindow.document.body.innerHTML)});
    41         
    42     };
    43     
    44 
    45 </script>
    复制代码

      附:关于 load() 方法的说明,见:http://www.cnblogs.com/HCJJ/p/5493821.html

     

    五、JQ 的 AJAX

     5.1 load()

    load方法是JQ中最简单最常用的Ajax方法。它默认采用GET请求,使用异步的方式,常用于请求一些静态的资源,例如HTML文件,然后插入到指定的DOM中。
    load方法也可以指定请求的参数与回调函数,一旦指定了请求参数,那么load方法则会采用POST方式请求页面。
    一个完整的load方法使用格式:
      load(url,params,callback); 
      url : 是被请求页面的url地址。若请求的页面是一个html文件,那么可以在url后面空一个空格然后附加一个选择器,便可以指定返回的内容,
      params : 请求时传递的参数,如果参数是一个对象,那么load便会使用POST方式请求,如果参数是一组键值对格式的字符串,那么则会采用GET请求。
      callback(data,status,xhr) : 请求完成时的回调函数。需要注意的是load方法的回调函数,不论请求成功还是失败,只要请求完成就会触发。
      data : 请求完成的值。
      status : 请求的状态
      xhr : XMLHttpRequest对象。

    示例:

    1 $('div').load('news.html .para');    //附加选择器
    2 $('div').load('index.php','v=v1')    //附加参数,GET请求
    3 $('div').load('index.php',{v:'v1'}) //附加参数,POST请求
    4 $('div').load('index.php',{v:'v1'},function(data){$(this).html(data)})

       5.2 $.get()

    $.get()方法使用GET方式来进行异步请求。
      $.get(url,params,callback) 
      params : 请求时传输的参数,可以是对象形式,也可以是一个序列化的字符串。
          对象格式:{v:'v1'}
          序列化的字符串:'v=v1&v2=v2';
      callback(data,status,xhr) : 注意的是,该函数只会在请求成功后才会被触发。
    示例:
         $.get('index.php',{v:'v1'},function(data){alert(data)}) 

       5.3 $.post()

    $.post()方法使用POST方式进行异步请求。
     $.post(url,params,callback); 

       5.4 $.getScript()

    $.getScript()方法会通过GET方式去请求一个脚本文件,并执行脚本代码。
       $.getScript(url,callback); 
         url : 脚本文件的url
         callback(data,status):请求后的回调函数,data是脚本的内容,而status则是请求的状态。

       5.5 $.getJson()

    $.getJson()与$.getScript()方法相同,不过$.getJson()方法专门用于请求json文件。
       $.getJson(url,callback); 
         url : json文件的url
         callback(data):请求后的回调函数,data是响应的数据。

       5.6 $.ajax()

    $.ajax()方法是JQ中最底层的AJAX方法,上面所说的都是基于$.ajax进行实现的。
    学习$.ajax()方法,我们可以从两个最基本点进行入手,就是属性与事件。

    a. 常用的属性说明:

    复制代码
    url:[str]:         指定请求页面的url。
    type:[str]:        设置请求的方式,是get还是post。
    dataType[str]:     设置期望的后台返回数据格式。JQ会根据你指定的dataType类型进行数据的解析,因此如果不确定数据类型,这个地方可以不填,默认为JQ自动判断。
    data:[str | obj]:  指定传输到后台的数据参数。
    async:[boolean]:   设置请求是同步方式还是异步方式,默认为异步。
    global:[boolean]:  设置是否开启AJAX的全局事件。
    timeout:[number]:  设置超时时间。一旦后台响应的时间超过timeout的值,那么AJAX就会跳转到error事件中,并且error事件中的xhr对象,会有一个statusText属性返回值为timeout。
    		    error:function(xhr){
    			if(xhr.statusText == 'timeout'){
    				alert('请求超时,请重新在试!');
    			}
    		     }
    jsonp:[str] : 后台会根据该值或得回调函数名称。
    复制代码


    b. 常用的事件说明:

    复制代码
    complete:当AJAX请求完成后触发的事件。
    success:当AJAX请求完成并且成功后触发的事件。
    error:当AJAX请求失败后触发的事件。
    beforeSend:在AJAX准备发送之前触发的事件。在该事件的处理程序中,可对当前AJAX的options做最后一次修改。
    		beforeSend:function(event,xhr){
    			xhr.type = 'get';
    			xhr.url = 'xxx.php';
    			event.success:function(){
    					
    			};
    		}
    复制代码


    c. 全局事件说明:

    当页面上存在任何ajax请求的时候都将触发这些特定的全局ajax事件处理函数。
    全局AJAX事件处理函数的注册与执行,都是有一个特定的顺序。

    如图:

    其中:ajaxSend、ajaxSuccess、ajaxError、ajaxComplete都可以被页面上所有的AJAX请求,而ajaxStart、ajaxStop则只会被触发一次。

    示例代码:

    复制代码
     1 var start = 0,
     2     send = 0;
     3 $(document).ajaxStart(function(){
     4     start++;
     5 });
     6 $(document).ajaxSend(function(){
     7     send++;
     8 });
     9 $.ajaxSetup({'async':false});
    10 $.ajax({...}) //ajax1;
    11 $.ajax({...}) //ajax2;
    12 
    13 console.log(start);  // --> 1;
    14 console.log(send);     // --> 2;
    复制代码

    因为ajaxSart()会在页面上的第一个请求发起时触发,ajaxStop()则会在最后一个请求结束时触发,所以它们常常组合用于显示loading等待框等。用来处理一群ajax请求。

    另外需要注意是:

    • 全局事件永远不会再跨域的脚本中运行,也不会再JSONP请求中运行。
    • 在jQuery1.8以上,所有的全局ajax事件处理函数必须绑定到document上,也就是$(document).ajaxEvent()
    • 只有在$.ajax()亦或$.ajaxSetup()中的globle设置成true才能使用ajax全局函数,false将不能使用。

      下面详细说明每个AJAX的全局事件:   

        · ajaxStart()   

      ajax的全局事件。ajax请求开始发送时执行。
      该事件处理函数不会被连续触发。
      格式:

    1 $(document).ajaxStart(function(e){
    2     if(e.type === 'ajaxStart'){
    3         alert('ajax请求开始!');
    4     }
    5 });

             *  e: 事件对象。

          · ajaxSend()

      ajax的全局事件。ajax请求发送时执行。
      该事件处理函数会被连续触发。
      格式:  $(document).ajaxSend(function(e,xhr,opt){});

    * e:事件对象。
    * xhr:XMLHttpRequest对象。
    * opt:ajax参数选项。

        · ajaxSuccess()

    ajax的全局事件。ajax请求成功时执行。
    该事件处理函数会被连续触发。
    格式: $(document).ajaxSuccess(function(e,xhr,opt,res){}); 

    * e:事件对象。
    * xhr:XMLHttpRequest对象。
    * opt:ajax参数选项。
    * res:ajax请求后 response返回的值。

    · ajaxError()

    ajax的全局事件。ajax请失败时执行。
    该事件处理函数会被连续触发。
    格式: $(document).ajaxError(function(e,xhr,opt,exc){}); 

    * e:事件对象。
    * xhr:XMLHttpRequest对象。
    * opt:ajax参数选项。
    * exc:失败原因。常见值:Not Found

    · ajaxComplete()

    ajax的全局事件。ajax请失败时执行。
    该事件处理函数会被连续触发。
    格式: $(document).ajaxError(function(e,xhr,opt){}); 

    * e:事件对象。
    * xhr:XMLHttpRequest对象。
    * opt:ajax参数选项。

    · ajaxStop()

    ajax的全局事件。ajax请求停止时执行。
    格式:

    1 $(document).ajaxStop(function(e){
    2     if(e.type === 'ajaxStop'){
    3         alert('ajax请求结束!');
    4     }
    5 });

    d. $.ajaxSetup()

    在JQ的AJAX中,还有一个$.ajaxSetup方法,它可以全局的设置AJAX的默认参数选项。
    示例:

    复制代码
     1 $.ajaxSetup({
     2     url:'index.php',
     3     type:'post',
     4     dataType:'json',
     5     error:function(){alert('error!!')}
     6 });
     7 
     8 oBtn.onclick=function(){
     9     $.ajax({
    10         success:function(){
    11             alert('success');
    12         }
    13     });
    14 }
    复制代码

       5.7 自己封装的一个Ajax

      再AJAX基础上再次封装,目的是减少书写AJAX代码的冗余。

    复制代码
     1 function ajaxGetData(_url,_data,fn,_async){
     2     $.ajax({
     3         type:'post',
     4         url:_url,
     5         async:!_async,
     6         dataType:'json',
     7         data:_data,
     8         success:function(data){
     9             fn && fn(data);
    10         },
    11         error:function(){
    12             alert('接口请求失败,失败地址:'+ _url);
    13         }
    14     });
    15 }
    复制代码

       5.8 序列化

    在以往使用AJAX结合表单向后台传输参数时,我们需要用JS一个一个寻找表单控件元素,然后再一一取值附加到AJAX请求上。这对只有少量字段的表单勉强还可以使用。但如果表单元素越来越复杂,再使用这种方法就显得缺乏弹性。
    Jquery为了解决这一常用的操作,提供了以下几个简便的方法,它们分别可以序列化与JSON格式化form表单元素的值。
       serialize()  - 序列化表单元素的值。所谓的序列化,就是以k=v的键值对格式并通过&进行连接的字符串。
       serializeArray()  - 该方法并不会返回字符串的值。而是将表单元素的值序列化为一个Json格式的数据。
    示例:

    1 $(form).serialize(); //name1=v1&name2=v2
    2 $(form).serializeArray(); //[{name:name1,v:v1},{name:name2,v:v2}]

    而实现serialize方法的核心功能,则是JQ的$.param()。
     $.params() 方法,可以将一个普通的对象序列化成一个键值对格式的字符串返回。
    示例: $.params({'key':'value'}); // 'key=value' 

    六、JSONP

     6.1 JSONP的概念

    JSONP(JavaScript Object Notaction With Padding) 就是采用JSON格式表示数据并由双方开发人员相互约定的一种数据传输方法,该协议并不是一种公开标准的协议。只是一个相互约定的使用方法。
    JSONP主要是利用HTML - script标签可以跨域的特性来解决跨域数据的传输与交换。(实际上含有src属性的HTML标记,都是可以跨域的)。
    JSONP的核心思路就是通过script标签去请求一个后台服务页面的地址。然后在该后台页面中,会调用前端HTML页面中的一个事先定义好的函数,并将处理的结果作为函数的参数一并传输过去。
    对于script标签而言,它不论src指向的url是一个*.js的文件,还是其他格式的文件,例如.php或者.jsp等,只要这个url指向的文件能返回一个符合JavaScript语法与格式的字符串即可。

      JSONP的基本工作流程如图所示:

      JSONP的基本工作流程代码实现如下

      · 前端代码 ·

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Document</title>
     6 </head>
     7 <body>
     8     
     9 </body>
    10 </html>
    11 <script src="http://hd.tzj.iwgame.com/js/jquery.min.js"></script>
    12 <script>
    13 
    14     function callback(v){
    15         alert(v);
    16     }
    17 
    18 
    19 </script>
    20 <script src="index.php"></script>
    复制代码

      · 后端代码 ·

    <?php
        $v = isset($_REQUEST['v'])? $_REQUEST['v'] : '"xxx"';
        echo 'callback('.$v.')';
    ?>

     6.2 自己封装的JSONP

    掌握JSONP的概念与基本的使用方式后,那么我们便可以封装一个公用的JSONP方法,该方法可以将请求的需求参数,与回调函数名称传输给后台,让后台自动的去生成所要回调的函数与结果。减少前端与后台的每次沟通成本。
    具体代码如下:

    复制代码
     1 function JSONP(params){
     2 
     3     var url = params.url,
     4         data = params.data,
     5         fn = params.callback,
     6         oScript = document.createElement('script'),
     7         hd = document.getElementsByTagName('head')[0],
     8         callback = 'jsonp_'+ new Date().getTime()%1e6;
     9 
    10     window[callback] = function(data){
    11         
    12         oScript.parentNode.removeChild(oScript);
    13         fn(data);
    14         window[callback] = undefined;
    15         try{delete window[callback];}catch(e){;}
    16 
    17     };
    18 
    19     oScript.src = url+'?data='+ data + '&callback=' + callback;
    20     hd.appendChild(oScript);
    21 
    22 }
    复制代码

        使用方式如下:

    1 JSONP({
    2     'url':'index.php',
    3     'data':'condition=lt30',
    4     'callback':function(data){alert(data)}
    5 });

        后台代码如下:

    复制代码
    1 <?php
    2     $fn = isset($_REQUEST['callback'])? $_REQUEST['callback'] : '';
    3     $data = isset($_REQUEST['data'])? $_REQUEST['data'] : '';
    4     if($fn){
    5         echo ''.$fn.'("'.$data.'")';
    6     }
    7 ?>
    复制代码


     6.3 JQ的JSONP使用。

        接下来我们再看下,基于$.ajax()方法实现的JSONP请求。

    复制代码
    1 $.ajax({
    2     type:'get',
    3     url:'index.php',
    4     dataType:'jsonp',    //指定期望的返回结果是一个JSONP
    5     jsonp:'callback',    //指定后台通过callback参数来接收到JQ自己创建的一个回调函数名称。
    6     data:'data=x',        
    7     success:function(data){alert(data)}
    8 });
    复制代码

       

        最后我们再总结一下,JSONP请求与传统的AJAX请求的区别,帮我们更好的区分与认识这两种机制。
          1. AJAX是基于XMLHttpRequest的并被同源策略所限制,而JSONP则是基于Script标签,可跨域的数据交换协议。
          2. AJAX的核心是XMLHttpRequest,它是一个已经标准化的协议,而JSONP则是一种相互约定非公开的协议。

  • 相关阅读:
    使用某些 DOCTYPE 时会导致 document.body.scrollTop 失效
    VB.NET 笔记1
    知识管理系统Data Solution研发日记之一 场景设计与需求列出
    知识管理系统Data Solution研发日记之五 网页下载,转换,导入
    折腾了这么多年的.NET开发,也只学会了这么几招 软件开发不是生活的全部,但是好的生活全靠它了
    分享制作精良的知识管理系统 博客园博客备份程序 Site Rebuild
    知识管理系统Data Solution研发日记之四 片段式数据解决方案
    知识管理系统Data Solution研发日记之二 应用程序系列
    知识管理系统Data Solution研发日记之七 源代码与解决方案
    知识管理系统Data Solution研发日记之三 文档解决方案
  • 原文地址:https://www.cnblogs.com/zhangxiaolei521/p/6012641.html
Copyright © 2011-2022 走看看