JSON 的 Keyname 到底要不要加双引号?

2022-03-30 11:04:38 +08:00
 3dwelcome
浏览器里用 eval()解析一个 json 对象,keyname 是可以不带双引号的,比如{a:123}是合法的。

然后同样是浏览器,用 JSON.parse()去解析一个 json 对象,就必须加双引号。否则直接报错!

规范就不能统一一下嘛,一声叹息。
5785 次点击
所在节点    前端开发
49 条回复
dcalsky
2022-03-30 11:05:57 +08:00
你是把 js object 和 JSON 弄混了吧?

定义: https://www.json.org/json-en.html
3dwelcome
2022-03-30 11:08:43 +08:00
@dcalsky 今天碰到一个后端数据,返回的是没有引号的 keyname JSON 。

我可以用 eval 来顺利解析,但总觉得很别扭。
westoy
2022-03-30 11:11:46 +08:00
一开始 gmail 大量使用 xhr, ajax 开始火了后,js object 替代 xml 成为数据标准后的一段时间确实有过很小一段时间的 eval parse 潮

于是就出现了大量的类似这样的 eval("{};console.log('helloworld') || { x: 1}")构造攻击案例

然后才出现了 json

最后现代浏览器才慢慢开始支持 JSON.stringify 和 JSON.parse......
nitmali
2022-03-30 11:13:09 +08:00
json 就是字符串,解析就是 js 对象
tyx1703
2022-03-30 11:18:12 +08:00
要加。
eval 是当成代码执行的,key 不加引号在 js 语法层面是正常语句。
westoy
2022-03-30 11:20:00 +08:00
@3dwelcome

让上游改吧, 正经的 json dump 库都是加双引号的, 没引号的估计是自己字符窜拼接出来的, 过滤不好可能埋雷的
icyalala
2022-03-30 11:20:40 +08:00
你不加引号,叫后端和客户端这些没有浏览器环境的地方怎么解析嘛,引入个 JSON5 解析器?
lovedebug
2022-03-30 11:21:24 +08:00
JSON 有 RFC 规范的,通用版本是需要双引号的

https://datatracker.ietf.org/doc/html/rfc8259
3dwelcome
2022-03-30 11:26:04 +08:00
@icyalala 理论上客户端用的 JSON 解析器,也能支持一下非引号的 keyname 吧。
shintendo
2022-03-30 11:27:32 +08:00
什么叫用 eval 解析,eval 是用来执行 js 代码的,只不过“碰巧”可以实现解析 json 的效果。
能用 eval 顺利执行说明是合法的 js ,不说明是合法的 json ,json 规范写的明明白白,key 必须带双引号。
shintendo
2022-03-30 11:32:24 +08:00
@3dwelcome 不符合规范,为啥要支持。你上面还说“规范就不能统一一下嘛”,现在又要求支持野生语法
3dwelcome
2022-03-30 11:38:17 +08:00
@shintendo 汗,怎么就成了野生语法。正常手写 js 对象,大家都是不加引号的。

我网上也搜了一下,强制引号是也有一定历史原因的,比如一些 js 语法关键词,早期解析时候就很容易失败,加个引号可以万无一失。

既然 json 标榜着人类可读性最高,那么就应该向更友好的书写,更友好的阅读发展。没有引号,显然更符合人类阅读,而不是机器阅读。
icyalala
2022-03-30 11:46:53 +08:00
@3dwelcome key 带引号是 JSON 规范,各种语言内置的 JSON 解析器和流行三方库基本都是按规范来的,尤其是一些为性能优化的库,比如 simdjson 。
“方便人类来写”的规范,那就是 yaml 或者 json5 了。
3dwelcome
2022-03-30 11:54:13 +08:00
@icyalala
原来还有 JSON5.parse()这个替代函数,发帖前还不知道,涨姿势了。

同时还支持了注释和单引号,果然够人性化,赞。
zhaol
2022-03-30 11:58:15 +08:00
eval 是解析 js 代码的,eval 的参数是 string 类型,但是它里面的规范是符合 js 规范的(也就是对象的 key 不用带双引号,只不过前后加了个双引号包裹起来这段 js 语句),所以正常解析。JSON.parse 的参数也是 stirng ,但是它里面的规范是要符合 JSON 的规范的(也就是对象的 key 要带双引号),这是两个不同 api ,干嘛要统一?
shintendo
2022-03-30 12:44:46 +08:00
@3dwelcome 汗,先分清楚 js 对象和 json 吧
3dwelcome
2022-03-30 12:46:27 +08:00


看着这张 google 的 jsonnet 图片,仿佛领悟到了什么。

首先,key 加双引号,肯定是反人类的。

然而,JSON 作为计算机交换格式,为了最大限度的避免解析错误,引号又是不可避免的。

于是,JS object 和 JSON 的关系,就变成了手写 JS object => 通过编译器变转译一次 => 变成机器可识别的 JSON 。
shintendo
2022-03-30 12:53:35 +08:00
@3dwelcome 不存在编译……JSON 是一个独立的数据交换格式,它的灵感来源于 JS 的对象语法,这是它们仅有的关联。
另外,JS 并不是任何时候都可以不写引号,而是某些 key 可以不写引号,某些 key 必须写引号,而了解 DC 的人都知道他对“做一件事只有一种方式”的偏执,所以在设计 JSON 的时候,既然不能统一不加引号,那就只能统一必须加引号。
shintendo
2022-03-30 12:59:21 +08:00
可以去搜一下 The JSON Saga 这个演讲,里面 DC 详细解释了 JSON 的设计过程。
他还提到一个趣事:JSON 的 License 里规定不能用来作恶,但是“作恶”是一个模糊的概念,所以 IBM 的法务写邮件问他,他就特别授权“IBM 可以用 JSON 来作恶”
wdssmq
2022-03-30 13:09:07 +08:00
@3dwelcome #12 人类可读性最高是 yml 谢谢。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/843806

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX