首页 > 代码库 > JSONP详解

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)容易编写和解析

JSONP详解