JSONP是一个非官方的协议,它容许在服务器端集成Script tags返回至客户端,经过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。本文主要介绍JSONP跨域原理,一块儿来看。javascript
JSONP是一个非官方的协议,它容许在服务器端集成Script tags返回至客户端,经过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。JSON系统开发方法是一种典型的面向数据结构的分析和设计方法,以活动为中心,一连串的活动的顺序组合成一个完整的工做进程。php
之因此会有跨域这个问题的产生根本缘由是浏览器的同源策略限制,理解同源策略的限制同源策略是指阻止代码得到或 者更改从另外一个域名下得到的文件或者信息。也就是说咱们的请求地址必须和当前网站的地指相同。同源策略经过隔离来实现对资源的保护。这个策略的历史很是悠 久从Netscape Navigator 2.0时代就开始了。html
解决这个限制的一个相对简单的办法就是在服务器端发送请求,服务器充当一个到达第三方资源的代理中继。虽然是用普遍可是这个方法却不够灵活。java
另外一个办法就是使用框架(frames),将第三方站点的资源包含进来,可是包含进来的资源一样要受到同源策略的限制。jquery
有一个很巧妙的办法就是在页面中使用动态代码元素,代码的源指向服务地址并在本身的代码中加载数据。当这些代码加载执行的时候,同源策略就不会起到 限制。可是若是代码试图下载文件的时候执行仍是会失败,幸运的是,咱们可使用JSON(JavaScript Object Notation)来改进这个应用。json
JSON和JSONP
api
与XML相比,JSON是一个轻量级的数据交换格式。JSON对于JavaScript开发人员充满魅力的缘由在于JSON自己就是Javascript中的对象。跨域
例如一个ticker对象浏览器
var ticker = {symbol:'IBM',price:100}安全
而JSON串就是 {symbol:'IBM',price:100}
这样咱们就能够在函数的参数中传递JSON数据。咱们很容易掌握在函数中使用动态的JSON参数数据,可是咱们的目的并非这个。
经过使咱们的函数可以加载动态的JSON数据,咱们就可以处理动态的数据,这项技术叫作 Dynamic Javascript Insertion。
咱们看下面的例子:
index.html中
<script type="text/javascript"> function showPrice(data){ alert("Symbol:" + data.symbol + ", Price:" + data.price); } var url = "ticker.js"; //Outer JS URL var script = document.createElement('script'); script.setAttribute('src', url); //load javascript document.getElementsByTagName('head')[0].appendChild(script); </script> ticker.js中 var data = {symbol:'IBM', price:100}; showPrice(data);
上面的代码经过动态加入Javascript代码,来执行函数加载数据。
正如以前提到过的,同源策略对于动态插入的代码不适用。也就是你能够从不一样的域中加载代码,来执行在他们代码中的JSON数据。
这就是JSONP(JSON with Padding)。注意,使用这种方法时,你必须在页面中定义回调函数,就像上例中的showPrice同样。
咱们一般所说的JSONP服务(远程JSON服务),实际上就是一种扩展的支持在用户定义函数中包含返回数据的能力。这种方法依赖于必须接受一个回调函数的名字做为参数。
而后执行这个函数,处理JSON数据,并显示在客户页面上。
JQuery的JSONP支持
从JQery 1.2之后,就开始支持JSONP的调用。在另外的一个域名中指定好回调函数名称,你就能够用下面的形式来就加载JSON数据。
url?callback=?
示例
jQuery.getJSON(url + "&callbak=?", function(data) { alert("Symbol:" + data.symbol + ", Price:" + data.price); });
jquery会在window对象中加载一个全局的函数,当代码插入时函数执行,执行完毕后就会被移除。同时jquery还对非跨域的请求进行了优化,若是这个请求是在同一个域名下那么他就会像正常的Ajax请求同样工做。
上例中咱们在动态插入到页面的代码中使用了静态的json数据,虽然完成了依次JSONP返回,但仍不是JSONP服务,由于不支持在URL中定义回调函数名称。下面是一个将其变成JSONP服务的一个方法
服务器端使用PHP。
首先咱们来定义接口的规范,就像这样:http://www.mydomain.com/jsonp/ticker?symbol=IBM&callback=showPrice
symbol是请求条件,callback是回调函数名称。
在页面文件中,咱们使用JQuery的支持:
//JQuery JSONP Support var url = "http://www.mydomain.com/api/suggest.php?symbol=IBM&callback=?"; jQuery.getJSON(url, function(data){ alert("Symbol:" + data.symbol + ", Price:" + data.price); });
在suggest.php中
$jsondata = "{symbol:'IBM', price:120}";
echo $_GET['callback'].'('.$jsondata.')';
如今,若是咱们想制做一些mashup,或者将第三方的资源整合到一个页面中,咱们就很容易想到JSONP的解决方法了。
注意:
JSONP是一个很是强大的构建mashp的方法,但是不是一个解决跨域访问问题的万能药。它也有一些缺点:
第一也是最重要的:JSONP不提供错误处理。若是动态插入的代码正常运行,你能够获得返回,可是若是失败了,那么什么都不会发生。你没法得到一个404的错误,也不能取消这个请求。
另一个重要的缺点是若是使用了不信任的服务会形成很大的安全隐患