`

Json & JsonP

 
阅读更多

如题,在网上查找JsonP的资料的时候,发现了下面这两篇文章是相当靠谱的:

http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/

http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html

 

详细的信息直接看上面的两篇文章再好不过了。

 

这里总结一下JsonP的原理思想:

Ajax处于安全等因素的考虑,不允许跨域请求资源(这个也符合所谓的同源策略),但是HTML标签中,含有src属性的标签却不受次限制,比如<javascrip>标签。

于是,聪明的程序员利用这个特点突破了没法直接使用Ajax方式获取非本域下的资源的限制。

 

比如:在www.a.com这个域下,需要获得www.b.com这个域下的一个Restful的数据。

这里,假设后者已经提供了类似http://www.b.com/xxx/getABC这样的Json返回数据的封装。

类似于下面这个样子的返回结果:

 

{"ABC":"I am ABC"}

 这样,最简单方式就是你直接在浏览器的地址栏里一敲http://www.b.com/xxx/getABC,就直接看到了上面的结果。

但是,悲剧的是:Ajax没法干这事(没法异步发个request到www.b.com/xxx/getABC,并且还获取返回结果),因为有上面说到的跨域限制。

 

那怎么办呢?

既然www.a.com自己没法直接请求www.b.com下的东东获得结果,但是www.b.com自己获得他下面的数据当然是没问题的。好吧,那www.a.com就和www.b.com谈判吧。后者对前者说,既然你要从我这里拿数据,那就得遵守协议啊!

为了获得数据,于是前者妥协了。。。

那么双方的协议是啥呢?

就是:www.a.com负责定义行为(就是定义javascript函数),然后把这个函数告诉www.b.com——通过把js函数名传给他的方式。(等等,不是不让跨域发请求吗?别忘了上面的蓝色字体强调的小后门哦。。。)

www.b.com统一规划什么数据能放出去,什么数据不能放出去给外人用。这里,在JsonP的处理方式下,他统一用Json的格式表示数据。在他允许放出的数据中,他接受www.a.com或者另外任何域名的js请求,并把数据放到传给他的js函数中。因为对于他来说,只要数据是可以放出来的,他不管www.a.com到底定义了啥js函数,这个js函数要干啥。

潜台词就是:数据给你了,你爱搞毛搞毛。。。爷不care!

 

用下面的这个链接可以看到最直观的效果:

http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=abc

返回的结果是这个样子的:

 

abc({"postalcodes":[{"adminName2":"Westchester","adminCode2":"119","postalcode":"10504","adminCode1":"NY","countryCode":"US","lng":-73.700942,"placeName":"Armonk","lat":41.136002,"adminName1":"New York"}]});

这个就是所谓的动态生成js的函数名啦!!!说白了就是,www.geonames.org上已经同意提供数据服务给其他众多的调用者,但是正因为调用者众多,www.geonames.org不可能事先知道各个调用者定义的js的函数名到底是啥,于是jsonp协议本身一个重要的方面就是规定了:调用者需要按照协议规定将你自己的js函数名告诉数据提供方!数据提供方根据调用者传入的js函数名,好人坐到底,将json数据包入这个方法中。这里例子就是上面的abc啦。

 

但是请注意,正是这个特殊的交互过程,使得这个js的调用和普通的js调用还真不太一样!

动态就动态在,这个js的行为和数据分离了,听起来有点违背OO的设计原则。

他的js的函数定义是由www.a.com给出的,他的js函数的入参,也就是数据是www.b.com生成的(注意,这里数据生成过程完全相当于本域内的请求,不是www.a.com哦,所以也就巧妙的绕过了Http的get请求的跨域的限制。)

 

上面描述的这个过程,单纯从js执行的角度去考虑,很像在www.a.com下的一个页面上,有下面这种形式定义的js:

<!--a js function named xxa has been defined in xxa.js-->
<script type="text/javascript" src="xxa.js"></script>
<!--the invocation of xxa with data happens in xxb.js-->
<script type="text/javascript" src="http://www.b.com/xxb.js"></script>
 总结一下,说到底,Json是内容表示的文本协议,而Jsonp是利用Json以及html的script标签的src属性实现跨域请求的传输协议
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics