JSON和JSONP的区别(转)

先前的概念中对JSON还是比较熟悉,对JSONP不是特别的清楚,整理完相关知识发现才豁然开朗。简单的说JSON是一种数据交换格式,而JSONP是一种非官方跨域数据交互协议。JSON是“暗号”,而JSONP则是接头方式。一个是描述信息的格式,一个是信息传递双方约定的方法。

一、什么是JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition – December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。

JSON建构于两种结构:

  • “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
  • 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。

这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

JSON具有以下这些形式:

对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。

JSON和JSONP的区别(转)_第1张图片

数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。

JSON和JSONP的区别(转)_第2张图片

值(value)可以是双引号括起来的字符串(string)、数值(number)、truefalse、 null、对象(object)或者数组(array)。这些结构可以嵌套。

JSON和JSONP的区别(转)_第3张图片

字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。

字符串(string)与C或者Java的字符串非常相似。

JSON和JSONP的区别(转)_第4张图片

数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

JSON和JSONP的区别(转)_第5张图片

空白可以加入到任何符号之间。 以下描述了完整的语言。

JSON的优点:

  1. 基于纯文本,跨平台传递极其简单;
  2. Javascript原生支持,后台语言几乎全部支持;
  3. 轻量级数据格式,占用字符数量极少,特别适合互联网传递;
  4. 可读性较强,虽然比不上XML那么一目了然,但在合理的依次缩进之后还是很容易识别的;
  5. 容易编写和解析,当然前提是你要知道数据结构;

JSON实例:

二、什么是JSONP?

JSONPJSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com 的服务器沟通,而 HTML 的 

服务器会在传给浏览器前将 JSON 数据填充到回调函数(parseResponse)中。浏览器得到的回应已不是单纯的资料叙述而是一个脚本。在本例中,浏览器得到的是:

虽然这个填充(前辍)“通常”是浏览器执行背景中定义的某个回调函数,它也可以是变量赋值、if 叙述或者是其他 JavaScript 叙述。JSONP 要求(也就是使用 JSONP 模式的请求)的回应不是 JSON 也不被当作 JSON 解析——回传内容可以是任意的运算式,甚至不需要有任何的 JSON,不过惯例上填充部份还是会触发函数调用的一小段 JavaScript 片段,而这个函数呼叫是作用在 JSON 格式的资料上的。

另一种说法—典型的 JSONP 就是把既有的 JSON API 用函数呼叫包起来以达到跨域存取的解法。为了要启动一个 JSONP 呼叫(或者说,使用这个模式),你需要一个 script 元素。因此,浏览器必须为每一个 JSONP 要求加(或是重用)一个新的、有所需 src 值的

< / head >
< body >
 
< / body >
< / html >

毫无疑问,页面将会弹出一个提示窗体,显示跨域调用成功。

2、现在我们在jsonp.html页面定义一个函数,然后在远程remote.js中传入数据进行调用。

jsonp.html页面代码如下:

remote.js文件代码如下:

localHandler({“result”:”我是远程js带来的数据”});
运行之后查看结果,页面成功弹出提示窗口,显示本地函数被跨域的远程js调用成功,并且还接收到了远程js带来的数据。很欣喜,跨域远程获取数据的目的基本实现了,但是又一个问题出现了,我怎么让远程js知道它应该调用的本地函数叫什么名字呢?毕竟是jsonp的服务者都要面对很多服务对象,而这些服务对象各自的本地函数都不相同啊?我们接着往下看。

聪明的开发者很容易想到,只要服务端提供的js脚本是动态生成的就行了呗,这样调用者可以传一个参数过去告诉服务端“我想要一段调用XXX函数的js代码,请你返回给我”,于是服务器就可以按照客户端的需求来生成js脚本并响应了。

看jsonp.html页面的代码:

这次的代码变化比较大,不再直接把远程js文件写死,而是编码实现动态查询,而这也正是jsonp客户端实现的核心部分,本例中的重点也就在于如何完成jsonp调用的全过程。

我们看到调用的url中传递了一个code参数,告诉服务器我要查的是CA1998次航班的信息,而callback参数则告诉服务器,我的本地回调函数叫做flightHandler,所以请把查询结果传入这个函数中进行调用。

OK,服务器很聪明,这个叫做flightResult.aspx的页面生成了一段这样的代码提供给jsonp.html(服务端的实现这里就不演示了,与你选用的语言无关,说到底就是拼接字符串):

我们看到,传递给flightHandler函数的是一个json,它描述了航班的基本信息。运行一下页面,成功弹出提示窗口,jsonp的执行全过程顺利完成!

4、到这里为止的话,相信你已经能够理解jsonp的客户端实现原理了吧?剩下的就是如何把代码封装一下,以便于与用户界面交互,从而实现多次和重复调用。

jQuery对JSONP的实现

我们依然沿用上面那个航班信息查询的例子,假定返回jsonp结果不变:

为什么我这次没有写flightHandler这个函数呢?而且竟然也运行成功了!这就是jQuery的功劳了,jquery在处理jsonp类型的ajax时自动帮你生成回调函数并把数据取出来供success属性方法来调用。

ajax与jsonp的异同

  1. ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
  2. 但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加

你可能感兴趣的:(Json,JSONP)