JSON中不允许出现的特殊字符及规范解析
JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其简洁、易读且易于机器解析的特性,已成为Web开发中数据传输的主流格式,无论是前后端数据交互、API接口返回,还是配置文件存储,JSON的规范性和兼容性都至关重要,许多开发者在使用JSON时,常因对字符限制的不熟悉导致解析错误,本文将详细解析JSON中不允许出现的特殊字符,并说明其背后的设计逻辑,帮助开发者规避常见陷阱。
JSON的核心语法规则与字符限制
JSON的语法严格基于两种结构:对象(Object)(用表示)和数组(Array)(用[]表示),数据以键值对(key: value)形式存在,且所有字符必须遵循Unicode标准,以下是JSON明确禁止或严格限制的字符类型:
控制字符(Control Characters, ASCII码0-31)
JSON标准明确规定,ASCII码在0-31之间的控制字符不允许直接出现在字符串中,这些字符因不可见且具有特殊控制功能(如换行、回车、制表符等),若直接嵌入字符串,会导致解析器无法正确识别数据边界。
| 控制字符 | ASCII码 | 含义 | 错误示例(❌) | 正确处理方式 |
|---|---|---|---|---|
NUL |
0 | 空字符 | "data\x00" |
转义为"\u0000"或移除 |
SOH |
1 | 标题开始 | "name\x01" |
转义为"\u0001" |
STX |
2 | 正文开始 | "text\x02" |
转义为"\u0002" |
LF |
10 | 换行(Line Feed) | "line1\nline2" |
转义为"line1\\nline2" |
CR |
13 | 回车(Carriage Return) | "text\r" |
转义为"text\\r" |
Tab |
9 | 水平制表符 | "col1\tcol2" |
转义为"col1\\tcol2" |
注意:虽然换行符(\n)、制表符(\t)等在代码中常用于格式化字符串,但在JSON中必须通过反斜杠\转义为\\n、\\t,否则会被视为控制字符导致语法错误。
未转义的双引号()和反斜杠(\)
JSON字符串的边界由双引号()定义,因此双引号必须转义,否则会被误认为字符串结束,同理,反斜杠(\)是JSON的转义字符,若需表示反斜杠本身,也必须转义。
-
未转义的双引号:
错误示例:{"name": "Tom "Jerry""}(第二个会被解析为字符串结束,导致后续Jerry"无法解析)。
正确写法:{"name": "Tom \"Jerry\""}(用\转义内部双引号)。 -
未转义的反斜杠:
错误示例:{"path": "C:\Users"}(\U会被误认为转义序列,导致解析失败)。
正确写法:{"path": "C:\\Users"}(用\\表示反斜杠)。
不允许尾随逗号(Trailing Commas)
JSON语法严格禁止在对象或数组的最后一个元素后添加逗号,这种写法在某些编程语言(如JavaScript、Python)中是允许的,但JSON标准不支持,会导致解析器报错。
-
对象中的尾随逗号:
错误示例:{"name": "Alice", "age": 25,}(age后的逗号多余)。
正确写法:{"name": "Alice", "age": 25}。 -
数组中的尾随逗号:
错误示例:[1, 2, 3,](3后的逗号多余)。
正确写法:[1, 2, 3]。
不允许注释(Comments)
JSON标准中不支持任何形式的注释(无论是单行注释还是多行注释),这与JSON的设计目标一致——作为纯数据格式,注释会增加解析复杂度,且无必要的数据传输价值,若需在JSON中添加说明,应在文档或代码层面处理,而非嵌入JSON本身。
错误示例:
{
// 用户信息
"name": "Bob",
/* 年龄 */
"age": 30
}
正确做法:将注释移至JSON文件外,或通过字段名间接说明(如"comment_user_info": "用户信息")。
数值类型中的特殊字符
JSON的数值(Number)类型仅支持(负号)、0-9(数字)、(小数点)、E/e(科学计数法)和(指数部分正号,如1e+3),不允许其他字符。
-
不允许千分位分隔符:
错误示例:{"price": 1,000.50}(逗号会被解析为字段分隔符)。
正确写法:{"price": 1000.50}。 -
不允许前导零(除非是0本身):
错误示例:{"code": 01}(前导零0无效)。
正确写法:{"code": 1}或{"code": 0}。 -
不允许特殊符号(如、):
错误示例:{"salary": "$5000"}(会被视为字符串内容,导致数值类型错误)。
正确写法:{"salary": 5000, "currency": "USD"}(数值与符号分离)。
Unicode字符的限制
JSON支持Unicode字符(包括非ASCII字符,如中文、emoji),但需满足以下条件:
- 不允许非配对的代理项(Unpaired Surrogates):
Unicode代理项(\uD800-\uDFFF)用于表示辅助平面字符(如emoji),必须成对出现(如\uD83D\uDE00表示😀),单个代理项(如\uD800)会导致解析错误。 - 不允许无效的Unicode转义序列:
转义格式必须为\uXXXX(XXXX为4位十六进制数),例如\u4e2d表示“中”,但\u12345(超过4位)或\u12G(非十六进制字符)无效。
为什么JSON要限制这些字符?
JSON的字符限制并非随意设计,而是基于以下核心原则:
-
简洁性与可解析性:
控制字符、注释等会增加解析器的复杂度,而JSON的目标是“轻量级”,无需支持这些非数据元素。 -
跨语言兼容性:
JSON需被JavaScript、Python、Java等多种语言解析,严格的字符规范能避免不同语言对特殊字符的处理差异(如某些语言允许尾随逗号,JSON不允许)。 -
数据安全性:
禁止未转义的双引号、反斜杠等,可防止注入攻击(如通过篡改字符串边界破坏JSON结构)。
常见错误与解决方案
错误1:字符串中包含未转义的换行符
错误代码:
{"log": "Error occurred\n at line 10"}
报错信息:Unexpected token \ in JSON(解析器遇到\n中的\,误认为转义字符,但后续n不符合转义序列)。
解决方案:转义换行符为\\n:
{"log": "Error occurred\\n at line 10"}
错误2:对象中尾随逗号
错误代码:
{"name": "Charlie", "age": 28,}
报错信息:Unexpected token } in JSON(解析器认为逗号后应有新字段,遇到时报错)。
解决方案:移除最后一个逗号:
{"name": "Charlie", "age": 28}


还没有评论,来说两句吧...