为什么JSON很重要?

26

我最近才听说JSON(JavaScript对象表示法)。 有人可以解释一下为什么它被认为很重要吗?除了它是“JavaScript原生”的之外,我们已经有XML了,为什么JSON更好呢?

编辑:嗯,主要答案的主题似乎是“它更小”。然而,它允许跨域数据获取的事实对我来说似乎很重要。或者在实践中还没有(或不太)被广泛使用吗?


8
我听说他们打算将XML改名为OEML(过度设计的标记语言)。 - Chad Grant
2
JSON如何处理不同的字符编码(就像XML一样)。在JSON表示中是否有隐含的字符编码? - Brian Agnew
1
允许从另一个域获取数据并不是XML或JSON格式固有的功能。这是与浏览器相关的事情。 - Mehrdad Afshari
3
根据RFC 4627中的"3.编码"章节,JSON文本必须使用Unicode编码。由于JSON文本的前两个字符始终为ASCII字符[RFC0020],因此可以通过查看前四个八位组中nulls的模式来确定八位字节流是UTF-8、UTF-16(BE或LE)还是UTF-32(BE或LE)。 - cic
10个回答

19

XML有几个缺点:

  • 它很笨重!
  • 它提供了内容的分层表示,但它与(但是非常类似于)Javascript对象模型并不完全相同。
  • Javascript无处不在。没有任何外部解析器,您可以直接使用JS解释器处理JSON。

显然,它并不意味着要完全取代XML。对于基于JS的Web应用程序,它的优势可能很有用。


1
“Javascript is available everywhere” 是什么意思?如果我将我的Java应用程序与CouchDb实例进行接口,我可以使用本地可用的XML解析器,但没有Javascript解析器。 - Brian Agnew
1
在这里,“到处”意味着“在每台电脑(具有现代浏览器)上”。 - Mehrdad Afshari
@Rabarberski:具有完全相同的对象模型也是一个巨大的优势,有时可能被低估了。 - Mehrdad Afshari
@Brian Agnew:几乎每种编程语言都有JSON解析库。请查看http://json.org/页面底部(其中大多数是用Java编写的)。 - barkmadley
2
@Cheeso - eval() 也不建议使用,因为它可能导致 XSS 攻击。 - Richard Szalay
显示剩余3条评论

13

JSON通常比其XML等效格式更小。较小的传输意味着更快的传输,从而导致更好的用户体验。


我不同意JSON更小的说法。<person name='John Doe' tags='friend male'/>是紧凑的XML格式,只有44个字符。相比之下,紧凑的JSON格式是:{person:{"name":"John Doe","tag":["friend","male"]}},共52个字符。这两者之间有25%的差距,XML更优。XML可能会更大,但不一定如此。 - Cheeso
4
我同意,因此使用了“一般”这个词。一旦你有了复杂项数组,XML 就比 JSON 更大了。你误读“一般”这个词是不值得扣分的。 - Richard Szalay
1
你的紧凑JSON格式不正确,应该是{"name":"John Doe","tag":["friend","male"]}。这使得它有45个字符,比XML仅多1个字符。 - Richard Szalay

12

JSON作为一种数据交换格式开始广泛使用,主要是因为它提供了一种规避Web浏览器中的同源策略并允许混合的方法。

假设您正在域A上编写Web服务。您无法从域B加载XML数据并解析它,因为这样做的唯一方式是XMLHttpRequest,而XMLHttpRequest最初仅限于与包含页面在同一个域中的URL通信。

事实证明,出于各种原因,您可以请求来自不同源头的<script>标签。聪明的人们意识到这是绕过XMLHttpRequest限制的好方法。服务器可以返回一系列JavaScript对象和数组常量,而不是返回XML。

(附加问题留给读者作为练习:为什么<script src="...">允许跨域而XHR不允许?)

当然,返回仅由对象字面量组成的<script>是没有用处的,因为如果不将值分配给某个变量,您将无法执行任何操作。因此,大多数服务使用JSON的一种变体,称为JSONP (http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/)。

随着混搭的流行,人们意识到JSON是一种方便的数据交换格式,尤其是当JavaScript在通道的一端时。例如,在Chromium中广泛使用JSON,即使在两端都使用C ++的情况下也是如此。这只是表示简单数据的一种不错的轻量级方式,并且许多语言都有良好的解析器可用。

有趣的是,使用<script>标签进行混搭非常不安全,因为本质上是故意进行XSS攻击。因此必须引入原生JSON (http://ejohn.org/blog/native-json-support-is-required/),这消除了该格式的最初好处。但是那时它已经非常流行了 :)


我不理解这个起源故事。编写一个返回(未解析的)XML文档的JavaScript函数非常简单。您可以使用此技巧轻松提供XML,就像使用它来提供全新的序列化格式一样容易。 - Robert Rossney
确实,您可以返回一个XML字符串,然后解析它。但是该字符串必须在JavaScript字符串内进行仔细转义。人们发现自己正在动态生成:returnData("<data foo="bar">...</foo>")...并且问自己为什么要麻烦,而不直接返回对象和数组。一旦您走上这条路,您就会意识到使用本地对象和数组而无需单独解析阶段只是一般而言更好的想法。但我认为混搭是JSON开始的方式,或者至少是其中几个主要原因之一。 - Aaron Boodman

11

JSON更加简洁。XML:

<person>
    <name>John Doe</name>
    <tags>
        <tag>friend</tag>
        <tag>male</tag>
   </tags>
</person>

JSON:

{"name": "John Doe", "tags": ["friend", "male"]}

此外,重叠的特征要少得多。例如,在XML中,选择使用元素(如上所示)与属性(<person name="John Doe">)之间存在紧张关系。


忽略多余的空格,大约是44个字符对比78个字符,但请记住,任何单个子元素(如名称)都可以被替换为属性(再节省约7个字符)。 - cletus
4
@Steve,自从什么时候在数据交换格式中阅读易懂性很重要了? - James
@Steve:JSON格式对人类更友好(当用于配置时是理想的),它比XML更易于阅读且更紧凑。 - Lawrence Dol
3
我认为可读性非常重要,但是您可以使用标记和换行符格式化JSON以匹配XML。 - Joel Coehoorn
1
我不同意JSON更小的说法。<person name='John Doe' tags='friend male'/>是紧凑的XML格式,只有44个字符。相比之下,紧凑的JSON格式是:{person:{"name":"John Doe","tag":["friend","male"]}},共52个字符。这两者之间有25%的差距,XML更优。XML可能会更大,但不一定如此。 - Cheeso

6

如果您正在使用Javascript,那么使用JSON会更加容易。这是因为JSON可以直接转换成Javascript对象,与DOM相比更易于操作。

借用并稍微修改上面的XML和JSON:

XML:

<person>
    <name>John Doe</name>
    <tag>friend</tag>
    <tag>male</tag>
</person>

JSON:

{ person: {"name": "John Doe", "tag": ["friend", "male"]} }

如果你想使用XML获取第二个标签对象,你需要使用功能强大但冗长的DOM API:

var tag2=xmlObj.getElementsByTagName("person")[0].getElementsByTagName("tag")[1];

如果使用通过JSON传输的JavaScript对象,您可以直接使用:

var tag2=jsonObj.person.tag[1];

当然,Jquery使DOM示例变得更加简单:
var tag2=$("person tag",xmlObj).get(1);

然而,JSON更适合JavaScript。如果您使用它一段时间,您会发现与涉及基于XML的数据相比,您的心理负担要少得多。

上述所有示例都忽略了一个或多个节点可用、重复或节点只有一个或没有子节点的可能性。然而,为了说明JSON的本地特性,使用jsonObj就只需要:

var tag2=(jsonObj.person && jsonObj.person.tags && jsonObj.person.tags.sort && jsonObj.person.tags.length==2 ? jsonObj.person.tags[1] : null);

(有些人可能不喜欢那么长的三元运算符,但它有效)。但是在我看来,XML会更加麻烦(我认为您不想采用三元运算符方法,因为您将不断调用dom方法,这取决于实现方式可能需要重新执行工作):

var tag2=null;
var persons=xmlObj.getElementsByTagName("person");
if(persons.length==1) {
    var tags=persons[0].getElementsByTagName("tag");
    if(tags.length==2) { tag2=tags[1]; }
}

Jquery(未经测试):

var tag2=$("person:only-child tag:nth-child(1)",xmlObj).get(0);

3

从第二个链接中,“如果数据格式为XML,则Ajax仅限于从Ajax应用程序来自的同一域(网站)获取数据。 如果数据格式为JSON,则Ajax可以跨越域旅行。”这不对,是吗? - Brian Agnew
布莱恩,我认为你是对的。建议将第二个链接视为可疑的 - 尽管它在某些地方未能实现目标,但它似乎只是在其任务中回答了问题。 - Sam Meldrum
这部分是正确的。我相信在Firefox中使用JSONp可以跨域旅行。 - cdmckay

2
这取决于你要做什么。这里有很多答案都更喜欢JSON而不是XML。如果你深入研究一下,其实并没有太大的区别。
如果你有一个对象树,那么你只会得到一棵JavaScript对象树。如果你想使用OOP风格访问它们,那么就会变得困难。假设你有一个类型为A、B、C的对象树,你可以很容易地将它们序列化为JSON。但是,如果你想读回来,你只会得到一棵JavaScript对象树。要重构你的A、B、C,你必须手动将值填充到手动创建的对象中,或者使用一些hack方法。这听起来像解析XML并创建对象吗?是的。
现在,只有最新的浏览器才支持原生的JSON。为了支持更多的浏览器,你有两个选择:a)在JavaScript中加载一个JSON解析器来帮助你解析。那么,这对于fatreeness来说听起来有多肥?我经常看到的另一个选择是eval。你可以在JSON字符串上执行eval()以获取对象。但这引入了一整套安全问题。JSON被规定不能包含函数。如果你没有检查对象是否包含函数,有人可以轻易地向你发送正在执行的代码。
所以,这可能取决于你更喜欢什么:JSON还是XML。最大的区别可能在于访问事物的方式,无论是脚本标记XMLHTTPRequest...我会根据这个来决定使用什么。在我看来,如果浏览器有适当的XPATH支持,我通常会选择使用XML。但时尚趋势是向JSON和在JavaScript中加载其他JSON解析器。
如果你不能决定,并且知道你需要一些非常强大的东西,你可能需要看一下YAML。阅读关于YAML的文章非常有趣,可以更深入地了解这个主题。但它真的取决于你要做什么。

1

JSON 是一种在 Javascript 对象中序列化数据的方式。其语法取自该语言,因此对于处理 Javascript 的开发人员来说应该很熟悉,并且作为对象的字符串化,它是浏览器内交互的更自然的序列化方法,比全面的 XML 派生(带有所有任意设计决策)更加轻量和直观。

它轻巧而直观。


1

JSON是一种基于文本的对象序列化格式,比XML更轻量级,并直接与JavaScript的对象模型集成。这就是它的大部分优点。

与XML相比,它的缺点大致有:可用工具较少(忘记标准验证和/或转换,更不用说在大多数编辑器中进行语法高亮或格式检查),不太可能人类可读(JSON和XML的可读性存在巨大差异,因此这是一个必然模糊的陈述),与JavaScript的紧密集成导致与其他环境的集成不够紧密。


0

不是因为它更好,而是因为它可以将许多东西联系在一起,允许无需手动解析的无缝数据传输!

例如 javascript -> C# Web 服务 -> javascript


考虑到即使在JavaScript中,由于安全原因,JSON通常也不会被eval(评估),所以我认为这并不能算作一个论点。 - B.E.
@Benedikt Eger - 有一个新的替代eval的函数将会在不带来eval风险的情况下解析JSON。此外,如果这个JSON来自可信的源,那么通常会被eval处理。 - stevehipwell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接