JSON
2014-06-29 19:24:48 阿炯

JSON 即 JavaScript Object Natation(JavaScript对象表示法),是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互。它已经成为今天Web开发过程中数据交互的事实标准,对那些应用 Ajax 的 Web 2.0 网站来说,JSON 确实是目前的不二之选。它与YAML同为XML的子集,但的确比它在Web方面的应用要广泛的多。


2013年,ECMA 正式推出 JSON 的国际标准,这意味着 JSON 格式已经变得与 XML 格式一样重要和正式了,两者皆是基于纯文本的数据格式。由于 JSON 天生是为 JavaScript 准备的,因此 JSON 的数据格式非常简单,可以用它来传输一个简单的 String,Number,Boolean,也可以传输一个数组或者一个复杂的 Object 对象。除了字符 ",\,/ 和一些控制符(\b,\f,\n,\r,\t)需要编码外,其他 Unicode 字符可以直接输出。JSON的格式描述可以参考RFC 4627。扩展名为'.json',互联网媒体类型为'application/json'。

它易于读写的同时也易于机器解析和生成。JSON格式是1999年《JavaScript Programming Language, Standard ECMA-262 3rd Edition》的子集合,所以可以在JavaScript以eval()函数(javascript通过eval()调用解析器)读入。不过这并不代表JSON无法使用于其他语言,事实上几乎所有与网络开发相关的语言都有JSON函数库。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

JSON是由美国程序员道格拉斯·克罗克福特构想和设计的一种轻量级资料交换格式。其内容由属性和值所组成,因此也有易于阅读和处理的优势。JSON是独立于编程语言的资料格式,其不仅是JavaScript的子集,也采用了C语言家族的习惯用法,目前也有许多编程语言都能够将其解析和字符串化,其广泛使用的程度也使其成为通用的资料格式。


格式说明

1.json文件由对象(集合)、数组、key/value元素组成,可以相互嵌套。
2.使用大括号包围的是对象,使用中括号包围的是数组,冒号分隔的是元素。
3.元素的key只能是字符串。
4.元素的value数据类型可以是:
    number:整数和浮点数都属于number类型,可以是正负数
    string:字符串
    bool:true/false
    array:使用中括号包围的部分是array
    object:使用大括号包围的是对象
    null:空,一般是这个值本来应该是某个object的,但是object不存在,于是为Null

5.对象、数组容器中每个元素之间使用逗号隔开,容器的最后一个元素不加逗号。
6.顶级对象都是匿名的,也就是没有key。

一般来说,json格式转换成语言中的数据结构时,有以下几个比较通用的规则(只是比较普通的方式,并非一定):
1.json对象映射成语言中的hash/struct,有时候没有合适的结构,将映射成类;其实class、hash、struct在数据组织方式上都是一样的,都是key/value的容器;

2.json数组映射成语言中的列表/数组/切片。

基本数据类型:

数值:十进制数,不能有前导0,可以为负数,可以有小数部分。还可以用e或者E表示指数部分。不能包含非数,如NaN。不区分整数与浮点数。JavaScript用双精度浮点数表示所有数值(后来也支持 BigInt)。

字符串:以双引号""括起来的零个或多个Unicode码位。支持反斜杠开始的转义字符序列。

布尔值:表示为true或者false。

数组:有序的零个或者多个值。每个值可以为任意类型。数组使用方括号[]包裹。多个数组元素之间用逗号,分隔,形如:[value, value]。

对象:若干无序的“键-值对”(key-value pairs),其中键只能是字符串。建议但不强制要求对象中的键是独一无二的。对象以花括号{}包裹。多个键-值对之间使用逗号,分隔。键与值之间用冒号:分隔。

空值:值写为null

token(6种标点符号、字符串、数值、3种字面量)之间可以存在有限的空白符并被忽略。四个特定字符被认为是空白符:空格符、水平制表符、回车符、换行符。空白符不能出现在token内部(但空格符可以出现在字符串内部)。JSON标准不允许有字节序掩码,不提供注释的句法。 一个有效的JSON文档的根节点必须是一个对象或一个数组。

JSON交换时必须编码为UTF-8。转义序列可以为:“\\”、“\"”、“\/”、“\b”、“\f”、“\n”、“\r”、“\t”,或Unicode16进制转义字符序列(\u后面跟随4位16进制数字)。对于不在基本多文种平面上的码位,必须用UTF-16代理对(surrogate pair)表示。

建构于两种结构:

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

值的有序列表(An ordered list of values)。在大部分语言中它被理解为数组(array)。


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

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


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



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


字符串
(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。这与C或者Java的字符串非常相似。


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


空白可以加入到任何符号之间。

关于 json 单引号和双引号区别,请使用双引号。


由于JSON是JavaScript的子集,所以一般都会使用eval()作为读取资料的方式,如果是针对可靠的数据来源,在不支持原生JSON解析的浏览器上面这是最快速的方法。然而由于eval方法同样可以执行任意的JavaScript代码,因此当数据来源不可靠时则可能产生安全问题。其中一种防止不安全代码出现的解决办法,是通过浏览器原生支持的JSON.parse(str)方法读取JSON资料,目前已经得到大部分主流浏览器的支持,在不支持原生JSON对象的浏览器上面可以使用parseJSON方法进行读取,其采用解析器验证读入的代码是否真的是JSON代码,这样就更安全。但由于这是用模拟的方式读取,速度上会比eval()慢一些。另外一个安全上的问题则是跨站请求伪造(Cross-site request forgery,简称CSRF或XSRF)。这个问题在JavaScript中的状况是,由于JavaScript采用了称为“沙盒”的机制,这种机制限制JavaScript引擎仅能引入同一个站点的代码,因而某种程度上提高了安全性。

JSONP

(JSON with Padding)是资料格式JSON的一种“使用模式”,可以让网页从别的网域获取资料。另一个解决这个问题的新方法是跨来源资源共享。扩展名为'.jsonp',互联网媒体类型为'application/json-p'。2005年夏由乔治·詹姆提(George Jempty)建议在JSON前面选择性的加上变量赋值,鲍勃·伊波利托(Bob Ippolito)于同年12月提出了JSONP最原始的提案,其中填充部分已经是回调函数。


由于同源策略,一般来说位于server1.freeoa.net的网页无法与 server2.freeoa.net的服务器沟通,而HTML的 <script>元素是一个例外。利用<script>元素的这个开放策略,网页可以得到从其他来源动态产生的JSON资料,而这种使用模式就是所谓的JSONP。用JSONP抓到的资料并不是JSON,而是任意的JavaScript,用JavaScript解释器执行而不是用JSON解析器解析。因此其也被称作是一种“让用户利用script元素注入的方式绕开同源策略”的方法。

如果远程的网站有JavaScript注入漏洞,原来的网站也会受到影响。现在有一个正在进行项目在定义所谓的JSON-P严格安全子集,使浏览器可以对MIME类别是“application/json-p”请求做强制处理。如果回应不能被解析为严格的JSON-P,浏览器可以丢出一个错误或忽略整个回应。

与其他格式的比较

XML

JSON与XML最大的不同在于XML是一个完整的标记语言,而JSON不是。这使得XML在程序判读上需要比较多的功夫。主要的原因在于XML的设计理念与JSON不同。XML利用标记语言的特性提供了绝佳的延展性(如XPath),在数据存储,扩展及高级检索方面具备对JSON的优势,而JSON则由于比XML更加小巧,以及浏览器的内置快速解析支持,使得其更适用于网络数据传输领域。

YAML

在功能和语法上,JSON 都是 YAML 语言的一个子集。特别是,YAML 1.2规范指定“任何JSON格式的文件都是YAML格式的有效文件"。最常见的YAML解析器也能够处理JSON。版本 1.2 之前的 YAML 规范没有完全涵盖 JSON,主要是由于 YAML 中缺乏本机 UTF-32 支持,以及对逗号分隔空格的要求;此外,JSON 规范还包括 /* */ 样式的注释。YAML 最重要的区别是语法扩展集,它们在 JSON 中没有类似物:关系数据支持:在 YAML 文档中,可以引用以前在文件/流中找到的锚点;通过这种方式,您可以表达递归结构。支持除基元之外的可扩展数据类型,如字符串、数字、布尔值等。支持带缩进的块语法;它允许您在不使用不必要的符号的情况下描述结构化数据:各种括号、引号等。

MessagePack

MessagePack宣称比JSON更短小,快速。


参考来源


官方主页:http://json.org/