JSONP详解

1.什么是ajax跨域请求
当通过ajax异步请求其他域名的服务时,存在跨域无权限访问的问题。
此时,可以通过JSONP来实现跨域请求。

2.JSONP原理
ajax异步请求无权限访问。但我们发现,web页面调用js文件时不存在跨域问题(如在我们的页面中引入百度地图API, <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=e3ZohdqyB0RL98hFOiC29xqh"></script>),总结发现,凡是拥有“src”属性的标签都拥有跨域的能力,如<script>,<img>,<iframe>等。
这种非正式的传输协议,就是JSONP。JSONP的一个要点是允许客户端传一个callback参数给服务器,然后服务器返回数据时会用这个callback参数作为函数名,包裹住JSON数据,返回客户端,客户端执行返回函数。

3.JSONP客户端具体实现
1)直接执行返回函数
本地服务器local.com下有个jsonp.html页面代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="http://remote.com/remote.js"></script>
</head>
<body>
</body>
</html>

远程服务器remote.com下有个remote.js文件代码如下:

alert('我是远程文件');

运行jsonp.html,会弹出“我是远程文件”,显示跨域调用成功。

2)客户端执行回调函数
jsonp.html页面代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>

</body>
</html>

remote.js文件代码如下:

localHandler({"result":"我是远程js带来的数据"});

运行jsonp.html,会弹出“我是远程js带来的数据”,显示跨域调用成功。

3)客户端传递回调函数
jsonp.html页面代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>

flightResult.aspx的页面生成了一段这样的代码提供给jsonp.html

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

运行jsonp.html,成功弹出提示窗口。

4)JSONP封装了3)中的代码,以方便客户端使用。
jsonp.html页面代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" >
 <head>
     <title>Untitled Page</title>
      <script type="text/javascript" src=jquery.min.js"></script>
      <script type="text/javascript">
     jQuery(document).ready(function(){ 
        $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
             jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
             success: function(json){
                 alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
             },
             error: function(){
                 alert('fail');
             }
         });
     });
     </script>
     </head>
  <body>
  </body>
 </html>

示例中没有定义flightHandler函数,但代码成功运行了。
这是因为jquery自动把success属性方法作为了回调函数。

4.JSONP总结
由上面的讲解可知,ajax和jsonp两种技术看起来很像,但实质上是完全不同。

5.JSON格式数据优点补充
1)基于纯文本,跨平台传递简单
2)javascript原生支持,后台语言几乎全部支持
3)可读性强
4)容易编写和解析

原文地址:https://www.cnblogs.com/shijingjing07/p/5929016.html