RFC4627中文版-JSON格式定义

本文详细解读了JSON数据交换格式的定义、语法、编码、解析器与生成器等核心概念,包括基础类型、结构类型、编码方式、安全性考虑以及互操作性。并提供了JSON在不同编程语言中的应用实例,以及与MIME媒体类型的关联。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RFC4627中文版-JSON格式定义

近期想稍微研究一下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文本是一个对象或者数组的序列化结果。


1

JSON - text = object / array

下面是6种结构字符:


1
2
3
4
5
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种结构字符前后都可以添加无意义的空白字符。


1
2
3
4
5
6
ws = * (
   % x20 / ; 空格

   % x09 / ; \ t 水平制表符

   % x0A / ; \ n 换行符

   % x0D ; \ r 回车符

)

2.1. 值

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


1
false null true

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


1
2
3
4

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是唯一的。


1
2

object = begin - object [ member * ( value - separator member ) ] end - object

member = string name - separator value

2.3. 数组

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


1

array = begin - array [ value * ( value - separator value ) ] end - array

2.4. 数字

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

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

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

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

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


1
2
3
4
5
6
7
8
9
10

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”


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

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)编码的。


1
2
3
4
5

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方法可以快速的确定是否满足该条件。


1

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对象:


1
2
3
4
5
6
7
8
9
10
11
12
13
{
     "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 ]

     }
}

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[ {

     "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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值