看完必会的JSONP

前端之家收集整理的这篇文章主要介绍了看完必会的JSONP前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

导读

  为了弥补AJAX无法跨域的问题,JSONP应运而生。不过JSONP并不是唯一跨域的技术,更新的有CORS技术。

简介

  JSONP是JSON with padding(填充式JSON或参数式JSON)的简写,是应用JSON的一种新方法。JSONP看起来和JSON差不多,只不过是被包含在函数调用中的JSON,就像下面这样。callback({ "name": "real"})。下面分别来谈谈JSON和JSONP。

JSON

JSON的优点

  • JSON是一种数据格式。
  • 基于纯文本,跨平台不是问题。
  • JavaScript原生支持。JSON是JavaScript的一个严格的子集,利用了JavaScript中的一些模式(对象、数组等)来表示结构化数据。
  • 经过合理的排版后可读性较强,XML过于繁琐、冗长。
  • 容易编写和解析(JSON.stringify、JSON.parse),前提是要知道格式。
  • @H_301_26@

    JSON数据的规则

      JSON的语法可以表示为以下三种类型的值。
      
    1、简单值:字符串,数值,布尔值,null。但不支持undefined。如:5,”hello”,false。值得注意的是:JSON字符串必须使用双引号(单引号会导致语法错误
    2、对象:”{}/Object”。对象是一种复杂数据类型。是一组无序的键值对。而每个键值对中的值可以使简单值(字符串),也可以是复杂数据类型(数组,对象)。

    {
      "name": "real","age": 20,"friends": ["Laki","Sonny"] }

    3、数组: “Array”。数组也是一种复杂数据类型,表示有序的值列表。其中数组中的值可以是简单数据类型(字符串),也可以复杂数据类型(数组、对象)。

    [
      {
        "name": "Laki","age": "21" },{
        "name": "Sonny","age": "22","friens": [ "real","Laki" ] }
    ]

      对于日期类型:
      

    var day = {
      date: new Date( 2016,10,2 )
    }
    var jsonDay = JSON.stringify( day );// 转换为JSON格式
    /* 解析 */
    var day2 = JSON.parse( jsonDay,function ( key,value) {
      if ( key === "date" ) {
        return new Date( value );
      } else {
        return value;
      }
    })

      是的,JSON.stringify()有三个参数,JSON.parse()有两个参数。只不过我们平常只用第一个。详细的可以参考其他资料。

    JSONP

    1、JSONP是为了解决跨域问题产生的,为了弥补AJAX的不足。AJAX请求跨域资源,Chrome下会报错:
      XMLHttpRequest cannot load http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost’ is therefore not allowed access.。说的是服务器端没有设置允许的请求源。
    后端头部信息加上Access-Control-Allow-Origin: *可以解决(CORS)。

    2、但是对于img、ifame、script等,我们发现,在它们的src中引用其他域的资源的时候,是可以加载的(对于iframe,如果跨域,虽然可以加载,但是无法进行DOM操作,postMessage可以解决)。

    3,JSONP正式基于上述的技术:

    • script标签
    • script的src加载其他跨域资源。
    • 在资源加载进来之前提前定义好一个函数,这个函数接受一个参数(数据),用这个函数来处理数据。
    • @H_301_26@

      4,上述的函数就是我们常说的callback函数函数名随意),callback函数接受数据(通常是json),进行解析并处理。

      /* 前台 */
      
      <script> window.onload = function () { var oBtn1 = document.getElementById( 'btn1' ); oBtn1.onclick = function () { var oScript = document.createElement( 'script' ); oScript.src = 'http://test.com/abc.PHP?t=str&callback=fn'; document.body.appendChild( oScript ); } } function fn( data ) { alert( data ); } function fn1 (data) { alert(data); } </script>
      /* 后台:http://test.com/abc.PHP */
      
      <?PHP
        $t = isset($_GET['t']) ? $_GET['t'] : 'num';
        $callback = isset($_GET['callback']) ? $_GET['callback'] : 'fn1';
      
        $arr1 = array('111111','22222222','33333333','4444444','555555555555555555555');
        $arr2 = array('aaaaaaaaaaaa','bbbbbbbb','cccccccccccc','ddddddddd','eeeeeeeeeeee');
      
        if ($t == 'num') {
          $data = json_encode($arr1);
        } else {
          $data = json_encode($arr2);
        }
      
        echo $callback.'('.$data.');';

        可以看到,我们传递的callback指定了要处理数据的函数
        
      5,如果我们不显示指明回调函数callback的话,那么会需要频繁的改动后台数据。
        比如对于上例,后台需要分别输出:
        echo 'fn('.$data.')';
        echo 'fn1('.$data.')';
        显然,这样是远远没有使用callback回调参数方便的。

      Jquery中JSONP的写法  

        好吧,可能大家都用的jq,这里就里jq来写一个。以上述第4点给出的前端代码为例,其Jquery写法是:

      $.ajax({ type: "get",url: "getData.PHP",dataType : 'jsonp',success: function ( data ) { console.log( data ); }
      });

       对上面那么点代码,又有一些有趣的探讨。
       
      Q:dataType : 'jsonp',不写行不行?
      A:不写会返回一个函数。参数是后端返回的数据。比如jQuery20009081766414813617_1475405628630(["111111","22222222","33333333","4444444","555555555555555555555"]);这是上述例子返回的。

      Q:可以手动指定回调函数吗?
      A:正如上面一个问答,我们看到,回调函数是jQuery生成的一个函数。如果我们手动指定,只需要success: fn1。然后自己定义一个fn1函数即可。

      Q:前端没指定callback,那么后端的$callback是什么?
      A:估计很多伙伴没有思考过这个问题。是”fn1”吗?答案是:不是。因为我们在请求的时候,jQ内部给我们手动添加了一个参数callback=***。这是我从chrome中看到的参数:
        callback:jQuery200039165487775940955_1475409598758
        _:1475409598759
      后面是时间参数,前面就不知道了。。所以我们在后端获取callback是可以获取到的。但是比方说改成callback2就不可以获取到了,那么,$callback = ‘fn1’。
        好了,关于jQuery中的jsonp暂时就介绍这么多,有机会再介绍。

      应用实例(百度搜索

        模拟百度搜索
        

      <!DOCTYPE HTML>
      <html>
      <head>
      <Meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>标题文档</title>
      <style> *{ margin: 0; padding: 0; } #q{ width: 300px;; height: 30px; padding: 5px; border: 1px solid #f90; font-size:16px; } #q:focus { /*outline:0;*/ border: 1px solid #f90; outline: 1px solid #f90; } #ul1 { display:none; border: 1px solid #f90; width:310px; } li a { display: block; width: 310px; height: 24px; padding: 5px 0; color: #666; text-decoration: none; } li a:hover { background: #f90; color: white; } </style>
      
      </head>
      
      <body>
        <input type="text" id="q" />
        <ul id="ul1">
      
        </ul>
      
      <script> window.onload = function () { var oQ = document.getElementById( 'q' ); var oUl = document.getElementById( 'ul1' ); oQ.onkeyup = function () { if ( this.value !== '' ) { var oScript = document.createElement( 'script' ); /*以json形式返回数据,否则返回array类型*/ oScript.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd='+ this.value +'&json=1&cb=customFunction&_'+ new Date().getTime(); document.body.appendChild( oScript ); } else { oUl.style.display = 'none'; } } } function customFunction (data) { console.log( data ); var html = '',oUl = document.getElementById( 'ul1' ); if ( data.s.length ) { //搜索结果存在,百度搜索搜索框值很多的时候,没有了结果。比如ddddddddddd... oUl.style.display = 'block'; for ( var i = 0,len = data.g.length; i < len; i++ ) { html += '<li><a href="https://www.baidu.com/s?ie=utf-8&wd='+ data.g[i].q +'">'+ data.g[i].q +'</a></li>'; } } oUl.innerHTML = html; } </script>
      </body>
      </html>

        关于对百度请求url。可参考我的另一篇文章http://www.jb51.cc/article/p-arswfmnn-od.html
        
        是不是和百度的一模一样呢。

      小结

        1,大致讲了JSON数据格式。
        2,JSONP的原理。
        3,JSONP模拟的百度搜索
        4,给出了JS操作JSONP和JQ操作JSONP的例子。

      参考

      JavaScript高级程序设计,第三版。

原文链接:https://www.f2er.com/json/289174.html

猜你在找的Json相关文章