文档章节

RFC4627中文版-JSON格式定义

laichendong
 laichendong
发布于 2014/06/25 09:27
字数 2306
阅读 209
收藏 0
近期想稍微研究一下JSON的序列化和反序列化。JSON格式大家都很熟悉,但大多来自于直观的认识。并没有了解过严格的定义。本着学习和练手的心态,将 RFC4627规范给翻译了一下。 感谢 @iwwy对我那错误满篇的翻译稿进行校对和修正。 ---------------------------------- 华丽的分割线 ---------------------------------- The application/json Media Type for JavaScript Object Notation (JSON) 本文(Memo)的状态

本文提供的是有关互联网通讯的内容。这不是任何形式的互联网标准,你可以随意传播本文而没有任何限制。

版权提示

Copyright (C) The Internet Society (2006)

摘要

JavaScript Object Notation (JSON)是一个轻量级的,基于文本的,跨语言的数据交换格式。它从ECMAScript编程语言标准(ECMAScript Programming Language Standard)衍生而来。JSON定义了一组用于表示结构化数据的可移植的格式化规则。

1. 简介

JavaScript Object Notation (JSON)是用于结构化数据序列化的一种文本格式。它基于ECMAScript Programming Language Standard, Third Edition [ECMA]定义的JavaScript对象字面量。

JSON包含4种基础类型(字符串,数字,布尔和null)和两种结构类型(对象和数组)

字符串是一个由零或者多个Unicode字符组成的序列。

对象是一个由零或者多个名/值对组成的无序集合,其中名/值对中名是字符串类型,值则可以是字符串,数字,布尔,null,对象或数组类型。

数组是一个由零或者多个值组成的有序序列。

术语“对象”和“数组”的叫法来源于JavaScript的习惯叫法。

JSON的设计目标是它应当是尽可能小的,可移植的,文本化的,并且可以作为JavaScript的一个子集。

1.1. 约定

本文中的"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD","SHOULD NOT", "RECOMMENDED", "MAY", 和 "OPTIONAL" 关键字意思遵从[RFC2119]中的定义。

本文中的语法规则遵从[RFC4234]中的定义。

2. JSON语法

一个JSON文本是一个标记(token)序列,标记包含6种结构字符,字符串,数字和3个字面量。

一个JSON文本是一个对象或者数组的序列化结果。

JSON-text = object / array

下面是6种结构字符:

begin-array     = ws %x5B ws  ; [ 左中括号
begin-object    = ws %x7B ws  ; { 左大括号
end-array       = ws %x5D ws  ; ] 右中括号
end-object      = ws %x7D ws  ; } 右大扩号
name-separator  = ws %x3A ws  ; : 冒号
value-separator = ws %x2C ws  ; , 逗号

6种结构字符前后都可以添加无意义的空白字符。

ws = *(
   %x20 / ; 空格
   %x09 / ; \t 水平制表符
   %x0A / ; \n 换行符
   %x0D ; \r 回车符
)
2.1. 值

JSON值MUST是一个对象,数组,数字,字符串或下列三个字面量之一:

false null true

字面量MUST是小写的,其他任何字面量都是不允许的。

value = false / null / true / object / array / number / string
false = %0x66.61.6c.73.65 ; false
null  = %0x6e.75.6c.6c ; null
true  = %0x74.72.75.65 ; true
2.2. 对象

对象结构表示为一对大括号包裹着0到多个名/值对(或者叫成员)。名/值对中名称是一个字符串,后面是一个冒号,用来分隔名称和值。值后面是一个逗号用来分隔值和下一个名/值对的名称。一个对象内的名称SHOULD是唯一的。

object = begin-object [ member *( value-separator member ) ] end-object
member = string name-separator value
2.3. 数组

数组结构表示为一对中括号包裹着0到多个值(或者叫元素)。值之间用逗号分隔。

array = begin-array [ value *( value-separator value ) ] end-array
2.4. 数字

数字的表示和其他大部分语言相似。数字包含一个以可选的减号为前缀的整数部分,其 后面可以跟有小数部分和/或指数部分。

八进制或者十六进制的形式是不允许的。以0开头也是不允许的。

小数部分是一个小数点后跟随一位或多位数字。

指数部分以不限大小写的字母E开头,之后可跟一个加号或减号。E和可选的符号后可 跟一位或多位数字。

不能被表示为数字的序列(例如,无穷大和NaN)的数字值是不允许的。

number        = [ minus ] int [ frac ] [ exp ]
decimal-point = %x2E                             ; .
digit1-9      = %x31-39                          ; 1-9
e             = %x65 / %x45                      ; e E
exp           = e [ minus / plus ] 1*DIGIT
frac          = decimal-point 1*DIGIT
int           = zero / ( digit1-9 *DIGIT )
minus         = %x2D                             ; -
plus          = %x2B                             ; +
zero          = %x30                             ; 0
2.5. 字符串

字符串的表示和C语言家族的处理方式相似。字符串用引号作为开头和结尾。除了以下一些必须被转义的字符以外所有的Unicode字符都可以直接被放在字符串中:引号("或'),反斜杠(\)和控制字符(U+0000 到 U+001F)。

任何字符都可以被转义。如果是在基本多语言平面(Basic Multilingual Plane (U+0000 到 U+FFFF))内,则应该表示为6字符序列:反斜杠后面跟一个小写字母u,再跟4位表示字符所在位置的16进制数字。16进制数字中的字母A-F可以是大写的,也可以是小写的。例如:一个只有一个反斜杠组成的字符串可以表示为"\u005C"。

另外,有一些流行的字符可以用两字符序列来转义,例如:一个只有一个反斜杠组成的字符串可以表示为"\\"。

要转义不在基本多语言平面(Basic Multilingual Plane)内的字符,则使用表示为UTF-16编码代理对(encoding the UTF-16 surrogate pair)的12字符序列。例如:一个只包含G谱字符(U+1D11E)的字符串可以被表示为"\uD834\uDD1E"

string        = quotation-mark *char quotation-mark
char          = unescaped / escape (
    0x22 /                                             ; " 引号 U+0022 
    0x5C /                                             ; \ 反斜杠 U+005c
    0x2F /                                             ; / 斜杠 U+002F
    0x62 /                                             ; b 退格符 U+0062
    0x66 /                                             ; f 分页符 U+0066
    0x6E /                                             ; n 换行符 U+006E
    0x72 /                                             ; r 回车符 U+0072
    0x74 /                                             ; t 水平制表符 U+0074
    0x75 4HEXDIG                                       ; uXXXX U+XXXX 
)
escape         = %x5C                                  ; \
quotation-mark = %x22                                  ; "
unescaped      = %x20-21 / %x23-5B / %x5D-10FFFF
3. 编码

JSON文本SHALL使用unicode编码。默认的编码方式为UTF-8。

由于JSON文本的头两个字符一定是ASCII字符[RFC0020],因此可以通过观察第一组4个8位字节来判断字节流是UTF-8,UTF-16(BE或LE)还是UTF-32(BE或LE)编码的。

00 00 00 xx UTF-32BE
00 xx 00 xx UTF-16BE
xx 00 00 00 UTF-32LE
xx 00 xx 00 UTF-16BE
xx xx xx xx UTF-8
4. 解析器

JSON解析器可以将JSON文本转换为其他表示方法。JSON解释器MUST能接受符合JSON语法的所有文本。JSON解析器MAY能接受非JSON形式的文本。

5. 生成器

JSON生成器能够生成JSON文本。其生成结果MUST严格符合JSON的语法。

6. IANA(互联网数字分配机构)方面的考虑

JSON文本的MIME媒体类型是application/json。

类型名称: application

子类型名称: json

必选参数: n/a

可选参数: n/a

编码方面的考虑: 如果是UTF-8则是8位字节,如果是UTF-16和UTF-32则是二进制

JSON可以用UTF-8,UTF-16和UTF-32编码表示。如果使用UTF-8,则JSON是8位字节兼容的。如果是UTF-16或UTF-32,则必须使用二进制内容传输编码。

安全方面的考虑:

通常,脚本语言都有安全问题,JSON作为JavaScript的一个子集,但由于它排除了分配和调用,所以它是安全的。

如果JSON文本中除去字符串部分的字符都是JSON标记(token)字符,则它可以安全的传递给JavaScript的eval()方法(用来编译和执行一个字符串的方法)。JavaScript中通过分别调用两个正则表达式的test和replace方法可以快速的确定是否满足该条件。

var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g, ''))) && eval('(' + text + ')');

互操作性方面的考虑:n/a

发布规范:RFC 4627

使用这个媒体类型的应用程序:

JSON曾被用于用以下所有编程语言编写的应用程序间传递数据:ActionScript, C, C#, ColdFusion, Common Lisp, E, Erlang, Java, JavaScript, Lua, Objective CAML, Perl, PHP, Python, Rebol, Ruby, and Scheme.

额外的信息:

魔术数字: n/a 文件扩展名: .json Macintosh文件类型的代码: TEXT

进一步的信息请联系:

Douglas Crockford douglas@crockford.com

预期的用法: COMMON

受限制的用法: 无

作者:

Douglas Crockford douglas@crockford.com

修改控制者:

Douglas Crockford douglas@crockford.com

7. 安全方面的考虑

参照第六节中的“安全方面的考虑”。

8. 举例

这是一个JSON对象:

{
	"Image": {
		"Width": 800,
		"Height": 600,
		"Title": "View from 15th Floor",
		"Thumbnail": {
		"Url": "http://www.example.com/image/481989943",
		"Height": 125,
		"Width": "100"
	},
	"IDs": [116, 943, 234, 38793]
	}
}

这是一个包含两个对象的数组:

[{
	"precision": "zip",
	"Latitude": 37.7668,
	"Longitude": -122.3959,
	"Address": "",
	"City": "SAN FRANCISCO",
	"State": "CA",
	"Zip": "94107",
	"Country": "US"

}
,{
	"precision": "zip",
	"Latitude": 37.371991,
	"Longitude": -122.026020,
	"Address": "",
	"City": "SUNNYVALE",
	"State": "CA",
	"Zip": "94085",
	"Country": "US"

}]
9. 参考文献 9.1. 参考的规范

[ECMA] European Computer Manufacturers Association, "ECMAScript Language Specification 3rd Edition", December 1999, <http://www.ecma-international.org/publications/files/ ecma-st/ECMA-262.pdf>.

[RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, October 1969.

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC4234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 4234, October 2005.

作者地址

Douglas Crockford JSON.org EMail: douglas@crockford.com

© 著作权归作者所有

共有 人打赏支持
laichendong
粉丝 10
博文 85
码字总数 71483
作品 0
朝阳
程序员
JavaScript Object Notation (JSON) Patch

I’m continuing my studying into what my new partner in crime Streamdata.io does, and part of this research is understanding the details of their technology stack. Today’s wor......

Kin Lane
2017/12/26
0
0
rebar.config的依赖包名称问题

问题出在rebar,rebar3没测试。 今天用rebar管理项目,在添加一个类库时遇到问题,类库地址为: https://github.com/tonyg/erlang-rfc4627 rebar.config里面这么写: {deps, [{erlang-rfc462...

格通
2016/02/24
225
0
android json解析及简单例子

JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不...

迷途d书童
2012/03/30
1K
0
android 中JSON的理解与解析

JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不...

Thanks
2013/02/19
0
3
【原创】各种 JSON 解析库的功能简介

这里增加一项无聊的对比图,看客自斟。 =================================== 【ruimaciel/mjson】 Last Update:2013-05-15(最新版本为 mjson-1.5 发布日期为 2012-08-22) description M'...

摩云飞
2013/01/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

hive分区

hive为啥分区? hive为了避免全表扫描,从而引进分区技术来将数据进行划分。减少不必要数据的扫描,从而提高效率。 hive的分区和MySQL的分区的区别? mysql分区字段用的是表内字段;而hive分...

Mr_yul
26分钟前
1
0
log4j2发送消息至Kafka

title: 自定义log4j2发送日志到Kafka tags: log4j2,kafka 为了给公司的大数据平台提供各项目组的日志,而又使各项目组在改动上无感知。做了一番调研后才发现log4j2默认有支持将日志发送到kaf...

微笑向暖wx
31分钟前
0
0
LINUX中如何查看某个端口是否被占用(转发)

LINUX中如何查看某个端口是否被占用 之前查询端口是否被占用一直搞不明白,问了好多人,终于搞懂了,现在总结下: 1.netstat -anp |grep 端口号 如下,我以3306为例,netstat -anp |grep 33...

覃大光
今天
1
0
JBolt 1.5.0新版发布,升级到支持最新版JFinal和Jetty,实现了在线更新插件功能

JBolt是一个JFinal极速开发框架 定制版IDE插件 目前仅有Eclipse插件版,Idea插件版正在开发中。 JBolt的详细使用教程请移步到这里 =====版本1.5.0 更新内容 2018年10月13日10:41:52===== 注意...

山东-小木
今天
0
0
laravel 微信支付

1.composer加载laravel微信支付第三方文件 composer require "overtrue/laravel-wechat:~4.0" composer require simplesoftwareio/simple-qrcode 1.3.* //composer生成二维码文件 2.改confi......

vio小黑
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部