可以在JSON中使用注释吗?


7600

我可以在JSON文件中使用注释吗?如果是这样,怎么办?


153
@StingyJack:解释可能不明显的事情,或者可能对评论做任何其他事情。我经常在数据文件中添加注释。XML,ini文件和许多其他格式包括注释规定。
Michael Burr

24
如果您像我一样,想知道//commentsSublime Text配置文件的特定用例是否可行,答案是肯定的(从版本2开始)。Sublime Text至少不会抱怨它,而它将{"__comment": ...}在控制台中抱怨,因为它是意外字段。
2013年

8
也许这就是为什么TOML创建一个原因..
亚历克斯·诺拉斯科

10
有点不愉快,但我也尝试使用//在JSON中进行注释。现在,我意识到它严格用于交换/交换。叹!我再也不能发表评论了:(。生命注定!!
2013年

Answers:


5584

没有。

JSON应该都是数据,如果包含注释,那么它也将是数据。

您可能有一个称为"_comment"(或其他名称)的指定数据元素,使用JSON数据的应用程序会忽略该数据元素。

在生成/接收JSON的过程中添加注释可能会更好,因为它们应该事先知道什么是JSON数据,或者至少知道其结构。

但是,如果您决定:

{
   "_comment": "comment text goes here...",
   "glossary": {
      "title": "example glossary",
      "GlossDiv": {
         "title": "S",
         "GlossList": {
            "GlossEntry": {
               "ID": "SGML",
               "SortAs": "SGML",
               "GlossTerm": "Standard Generalized Markup Language",
               "Acronym": "SGML",
               "Abbrev": "ISO 8879:1986",
               "GlossDef": {
                  "para": "A meta-markup language, used to create markup languages such as DocBook.",
                  "GlossSeeAlso": ["GML", "XML"]
               },
               "GlossSee": "markup"
            }
         }
      }
   }
}

232
如果存在一个有效的名为comment的字段,则可能需要在实际注释上加上某种前缀:"__comment":"comment text goes here...",
Rob Fonseca-Ensor 2010年

19
顺便说一句,Java google-gson的json库支持注释。
centic

11
如果我想对AccronymAbbrev属性分别发表评论怎么办?我之前曾使用过这种模式,但由于不允许这样做而停止了使用。这是一个hack。也许如果我在前面加上一个属性名称__comment__。那是“ __comment__Abbrev”,仍然是一个hack,但是让我对所有特征进行评论
Juan Mendes

41
您也可以使用“ //”:这看起来更
自然

4
当将JSON用于人类期望的配置文件时,应该对它们进行注释,以使人类更好地理解。带有注释的此类文件不再是有效的JSON,但是有解决方案。例如,Google的GYP支持#样式的注释。JSON.Minify将帮助您从输入文件中丢弃C / C ++样式注释。
ПетърПетров

1841

,格式为的注释//…/*…*/JSON中不允许使用。该答案基于:

  • http://www.json.org
  • RFC 4627application/jsonJavaScript对象符号(JSON)的媒体类型
  • RFC 8259 JavaScript对象表示法(JSON)数据交换格式(取代RFC 4627、7158、7159)

67
如果您想用注释注释JSON(因此使其成为无效的JSON),请在解析或传输之前将其最小化。Crockford本人在2012年的配置文件中承认了这一点。

24
@alkuzad:在形式语法方面,必须有明确表明允许它们的内容,而不是相反。例如,选择您的编程语言:只是因为某些显着(但缺少)的功能没有被明确禁止,并不意味着您的编译器会神奇地识别它。
stakx-不再贡献

5
是。JSON格式在元素之间有很多死区,并且在那些区域中对空间不敏感,因此没有理由在此不能有单行或多行注释。许多解析器和简化器也支持JSON注释,因此只需确保您的解析器支持它们即可。JSON用于应用程序数据和配置设置,因此现在需要注释。“官方规格”是一个不错的主意,但是它不够充分且过时,因此太糟糕了。如果您担心有效负载大小或性能,请缩小您的JSON。
Triynko

58
尽管您的回答绝对正确,但是应该说这是BS。如此众多的最终用户遇到了对json配置的需求,因此注释非常有帮助。仅仅因为有些锡箔纸帽子认为JSON 并且必须始终是机器可读的,却忽略了人类需要阅读它的事实,这简直是一种小小的头脑。
cmroanirgo

18
@cmroanirgo:您显然不是第一个抱怨JSON的局限性的人……这就是为什么我们有解析器可以静默地允许注释以及YAML和JSON5等其他格式的原因。但是,这并没有改变JSON就是事实。相反,我发现有趣的是,由于存在局限性,人们开始将JSON用于最初显然还不够的目的。不要怪JSON格式;怪我们坚持在不合适的地方使用它。
stakx-不再贡献

802

如果选择,请添加评论;在解析或传输之前,先用减法器将其剥离。

我刚刚发布了JSON.minify(),它从JSON块中删除了注释和空格,并使之成为可以解析的有效JSON。因此,您可以像这样使用它:

JSON.parse(JSON.minify(my_str));

当我发布它时,我什至遭到了人们的强烈反对,甚至连想法都没有。所以我决定写一篇关于为什么在JSON中有意义的博客文章。它包含JSON创建者的以下著名注释:

假设您正在使用JSON保留要注释的配置文件。继续并插入您喜欢的所有评论。然后,将其通过JSMin传递给JSON分析器。- 道格拉斯·克罗克福德Douglas Crockford),2012年

希望这对那些不同意为什么JSON.minify()有用的人有所帮助。


153
我对JSON.minify()的唯一问题是它真的很慢。因此,我做了自己的实现相同功能的实现:gist.github.com/1170297。在一些大型测试文件上,您的实现需要74秒,而我的需要0.06秒。
WizKid 2011年

56
如果您可以将建议的替代算法提交给JSON.minify()的github存储库,那就太好了,以便可以将其移植到所有受支持的langs: github.com/getify/json.minify
Kyle Simpson

16
@MiniGod我已经多次听到道格对这个话题的想法。我很早以前在我的博客文章中对它们进行了处理:blog.getify.com/json-comments
凯尔·辛普森

18
@ MarnenLaibow-Koser仍然有注释的有效用法,甚至用于数据流(甚至数据包):XML都包含诸如创建时间或来源之类的诊断元数据,这在XML中很常见,对于JSON数据也非常明智。反对注释的争论很浅,任何文本数据格式都应允许注释,无论暗示的用途是什么(规范都没有建议JSON不能在其他地方使用,fwiw)
StaxMan 2014年

18
如果JSON要具有普遍接受性(基本上是这样做的),那么它应该具有普遍性应用程序。示例:JSON可以用作应用程序配置文件。此应用程序需要评论。
eggmatters

441

根据设计,注释已从JSON中删除。

我从JSON中删除了注释,因为我看到人们正在使用它们保留解析指令,这种做法会破坏互操作性。我知道缺少评论会使某些人感到难过,但事实并非如此。

假设您正在使用JSON保留要注释的配置文件。继续并插入您喜欢的所有评论。然后将其通过JSMin传递给JSON解析器。

资料来源:道格拉斯·克罗克福德(Douglas Crockford)关于Google+的公开声明


198
我认为JSON应该比XML更具可读性?注释是为了提高可读性。
intrepidis 2012年

25
无论如何,您可能很调皮,并在JSON中添加了解析指令:{“ __directives”:{“#n#”:“ DateTime.Now”},“ validdate”:“#n#”} ...看起来像YAML那是前进的方向……
intrepidis 2012年

73
个人意见:不允许发表评论是la脚的。除了构建一个忽略注释的非标准JSON解析器以解码配置文件外,我别无选择。
caiosm1005 2013年

17
@ArturCzajka我仍然不喜欢JSON不支持注释的事实,但是我尝试了INI,并且我必须承认,将它们通过JSON用于配置文件更有意义。感谢您的回复,希望更多的人在阅读此对话时会改变主意。(无论如何,使解析器更像是一种练习:)
caiosm1005

77
这就像要求所有自行车都装有训练轮,因为有些人不能骑自行车。删除一个重要功能是因为愚蠢的人滥用了它是不好的设计。数据格式应优先考虑可用性,而不是防白痴。
Phil Goetz

205

免责声明:您的保修无效

正如已经指出的那样,这种黑客利用了规范的实现。并非所有JSON解析器都会理解这种JSON。流解析器尤其会阻塞。

这是一个有趣的好奇心,但是您真的不应该将它用于任何用途。以下是原始答案。


我发现了一个小技巧,可让您在不影响解析或更改以任何方式表示的数据的JSON文件中放置注释。

似乎在声明对象文字时,可以使用相同的键指定两个值,最后一个优先。信不信由你,它证明了JSON解析器的工作原理相同。因此,我们可以使用它在源JSON中创建注释,这些注释将不会出现在已解析的对象表示中。

({a: 1, a: 2});
// => Object {a: 2}
Object.keys(JSON.parse('{"a": 1, "a": 2}')).length; 
// => 1

如果我们应用此技术,则您注释的JSON文件可能如下所示:

{
  "api_host" : "The hostname of your API server. You may also specify the port.",
  "api_host" : "hodorhodor.com",

  "retry_interval" : "The interval in seconds between retrying failed API calls",
  "retry_interval" : 10,

  "auth_token" : "The authentication token. It is available in your developer dashboard under 'Settings'",
  "auth_token" : "5ad0eb93697215bc0d48a7b69aa6fb8b",

  "favorite_numbers": "An array containing my all-time favorite numbers",
  "favorite_numbers": [19, 13, 53]
}

上面的代码是有效的JSON。如果您解析它,您将得到一个这样的对象:

{
    "api_host": "hodorhodor.com",
    "retry_interval": 10,
    "auth_token": "5ad0eb93697215bc0d48a7b69aa6fb8b",
    "favorite_numbers": [19,13,53]
}

这意味着没有评论的痕迹,并且它们不会有怪异的副作用。

骇客入侵!


150
根据规范:对象内的名称应唯一。
昆汀

113
“所有实现都处理相同” —这很难证明。
昆汀

91
不保证JSON中元素的顺序。这意味着“最后一个”项目可能会改变!
2013

66
这显然违反了规范(请参见上面的注释),请不要这样做。ietf.org/rfc/rfc4627.txt?number=4627
voidlogic

333
-如果解析器正在流式传输,该怎么办?如果解析器将其读入未定义键顺序的字典中怎么办?用火杀死它
deanWombourne 2013年

183

JSON不支持注释。也从未打算将其用于需要注释的配置文件。

Hjson是人类的配置文件格式。轻松的语法,更少的错误,更多的注释。

Hjson简介

有关JavaScript,Java,Python,PHP,Rust,Go,Ruby和C#库的信息,请参见hjson.org


13
已投票。显然,开放的保守派人士会很讨厌恨。我希望您的实现获得更多了解-甚至可能比原始实现更受欢迎;)我希望有人也可以使用Ruby实现它。@adelphus定义明确的语言是您自己的观点或看法。如果你是一个保守的“开发者”,那并不能证明你更好,而将自己锁在有限的空间里甚至更糟。不要轻易将人们视为可怕的开发人员。
konsolebox 2014年

7
抱歉,@ konsolebox。阅读ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf后,也许您可​​能会重新考虑“定义明确的JSON是您的意见”视图。这是一个真正的标准,开发人员将实现自己的“特殊”版本导致碎片化,混乱和大量浪费的时间。看一下编写代码时,Web开发人员所面临的困境,仅仅是因为每个浏览器实现的标准版本略有不同。JSON语言可能并不完美,但是碎片化更糟。是的,这只是一种意见,您可以自由地不同意。
adelphus 2014年

22
我很佩服您的进取心,但是您有点在重新发明YAML。如果您想获得很大的灵活性和可读性,请使用YAML(实际上不要:stackoverflow.com/questions/450399/…)或坚持使用礼节性但毫不含糊的JSON。

4
我发现最人性化的配置格式仍然是INI。它很简单,语法也不太繁重。这使得用户仅将脚趾浸入配置池中就不会感到恐惧。
马特

14
当你需要JSON作为配置(这里的评论需要) -命名文件“的.js”,而不是“以.json” .. JS当然可以处理任何有效的JSON对象,并且还可以处理意见..这就是它之所以“ webpack.config.js”而不是“ webpack.config.json”(以及在webpack中也有很多原因:P)
jebbie 2016年

122

考虑使用YAML。它几乎是JSON的超集(几乎所有有效的JSON都是有效的YAML),并且允许注释。


12
@ g33kz0r正确,因此我将YAML描述为JSON的近超集。
Marnen Laibow-Koser 2012年

12
@NateS许多人已经指出答案是否定的。我建议了一种更好的方法来实现OP的目标。那就是答案。
Marnen Laibow-Koser 2014年

5
缺点:yamlPython并未随附库。
流血的手指

6
@ marnen-laibow-koser:是的,使用Java和Perl的可用YAML库并期望彼此产生的YAML不会被错误使用,肯定是没有能力的。YAML互操作是一个问题,但JSON互操作不是问题,这完全是由于我缺乏知识所致。
toolbear

3
@ marnen-laibow-koser,一种使用更简单的规范完成相同任务的格式会更好。具有完美实现的实用格式优于具有不完美实现的理想格式。并非所有错误的库责备都落在实现者的肩膀上。YAML规范长,密且钝。它在Wikipedia条目中列举了两个歧义示例。如果必须将发射者置于人与格式之间以保护他们免受歧义,则格式将失去其人性化的主张。JSON声明较少,大多数情况下成功,而YAML声明较多且不足。
toolbear 2014年

108

你不能 至少快速浏览一下json.org是我的经验。

JSON在该页面上显示了其语法。关于评论没有任何注释。


67

注释不是官方标准,尽管某些解析器支持C ++样式的注释。我使用的一个是JsonCpp。在示例中有一个:

// Configuration options
{
    // Default encoding for text
    "encoding" : "UTF-8",

    // Plug-ins loaded at start-up
    "plug-ins" : [
        "python",
        "c++",
        "ruby"
        ],

    // Tab indent size
    "indent" : { "length" : 3, "use_space": true }
}

jsonlint不对此进行验证。因此,注释是解析器特定的扩展,而不是标准的。

另一个解析器是JSON5

JSON TOML的替代方法。

另一个选择是jsonc


Groovy具有一些用于处理JSON的内置类。JsonSlurper可以处理评论。当然,官方规范中不允许注释,因此任何解析器中的这种行为都是非标准且不可移植的。
izrik 2015年

Newtonsoft Json.NET还支持C风格的注释,没有任何问题
马克斯

66

您应该改为编写JSON模式。JSON模式是当前提议的Internet草案规范。除了文档之外,该模式还可以用于验证JSON数据。

例:

{
    "description":"A person",
    "type":"object",
    "properties":
        {
            "name":
                {
                    "type":"string"
                },
            "age":
                {
                    "type":"integer",
                    "maximum":125
                }
        }
}

您可以通过使用描述架构属性来提供文档。


5
JSON模式是否还存在?它存在,但是任何已知的库都支持它吗?
Munhitsu 2012年

1
是的,json-schema google组非常活跃,我建议使用JSV作为JSON Schema验证程序的良好JavaScript实现。
raffel 2012年

5
这仅对结构化文档
Juan Mendes

如果您使用clojure(我确定您没有),那么这里有一个功能合理的开源JSON模式解析器:github.com/bigmlcom/closchema
charleslparker 2013年

@Munhitsu Manatee.Json(.Net)广泛支持JSON模式。
gregsdennis 2015年

64

如果您将Jackson用作JSON解析器,则可以通过以下方式启用它以允许注释:

ObjectMapper mapper = new ObjectMapper().configure(Feature.ALLOW_COMMENTS, true);

然后您可以有这样的评论:

{
  key: "value" // Comment
}

您还可以#通过设置以下内容开始注释:

mapper.configure(Feature.ALLOW_YAML_COMMENTS, true);

但是总的来说(如前所述),该规范不允许发表评论。


50

这是我在Google Firebase文档中找到的内容,可让您将注释放入JSON:

{
  "//": "Some browsers will use this to enable push notifications.",
  "//": "It is the same for all projects, this is not your project's sender ID",
  "gcm_sender_id": "1234567890"
}

仅供参考,Firebase实时数据库不允许在键中使用'/'。因此这可能是您自己使用的不错的约定,但是您不能在Firebase中做到这一点
gutte

5
此方法破坏了一些库,这些库要求密钥必须唯一。我正在通过给评论编号来解决该问题。
MovGP0

很好的评论,我在SO上发现了这个问题...这部分似乎未被规范stackoverflow.com/questions/21832701/…
Mana

4
我现在倾向于这样使用它:{“ // foo”:“ foo comment”,“ foo”:“ foo value”,“ // bar”:“ bar comment”,“ bar”:“ bar value”}您可以对多个注释使用数组:{“ // foo”:[“ foo注释1”,“ foo注释2”],“ foo”:“ foo值”}
MovGP0

47

NO。JSON曾经支持注释,但是它们被滥用并从标准中删除。

来自JSON的创建者:

我从JSON中删除了注释,因为我看到人们正在使用它们保留解析指令,这种做法会破坏互操作性。我知道缺少评论会使某些人感到难过,但事实并非如此。- 道格拉斯·克罗克福德Douglas Crockford),2012年

官方JSON网站位于JSON.org。JSON被ECMA International 定义为标准。总有一个请愿程序来修改标准。由于多种原因,注释不太可能被添加到JSON标准中。

通过设计,JSON是XML的一种易于反向工程(人工分析)的替代方案。甚至简化到不需要注释的地步。它甚至不是标记语言。目标是稳定和互操作性。

任何了解面向对象的“具有”关系的人都可以理解任何JSON结构-这就是重点。它只是带有节点标签(键/值对)的有向无环图(DAG),这是一种几乎通用的数据结构。

唯一需要的注释可能是“ //这些是DAG标签”。键名可以根据需要提供丰富的信息,从而允许任意语义上的统一。

任何平台都可以仅用几行代码来解析JSON。XML需要复杂的OO库,这些库在许多平台上都不可行。

注释只会使JSON的互操作性降低。除非您真正需要的是标记语言(XML),否则根本就没有其他要添加的内容,并且不关心持久性数据是否易于解析。

作为JSON的创建者,也观察到,一直有JS管道支持注释:

继续并插入您喜欢的所有评论。然后,将其通过JSMin传递给JSON分析器。- 道格拉斯·克罗克福德Douglas Crockford),2012年


37

如果您的文本文件(它是JSON字符串)将由某个程序读取,那么在使用它之前剥离C或C ++样式的注释会有多困难?

答:那将是一个班轮。如果这样做,则可以将JSON文件用作配置文件。


1
可能是迄今为止最好的建议,尽管将文件保留为交换格式仍然是一个问题,因为文件在使用前需要进行预处理。
2011年

我同意,并且已经用Java编写了JSON解析器,该解析器可以从www.SoftwareMonkey.org获得。
劳伦斯·多尔

2
尽管我认为,扩展JSON(不称其为其他交换格式)不是一个好主意:请确保忽略字符串中的“注释”。{“ foo”:“ / *这不是评论。* /”}
stofl 2013年

27
嗯,不,实际上,JSON不是正则语法可以简单地找到匹配的/ *对的正则语法。您必须解析文件以查找/ *是否出现在字符串内(并忽略它),或者它是否已转义(并忽略它)等。而且,您的答案也无济于事,因为您只是推测(错误地)而不是提供任何解决方案。
凯尔·辛普森

1
@ kyle-simpson说了什么。而且,他太谦虚了,无法引导读者对自己使用JSON.minify作为临时正则表达式的替代方法的回答。这样做,不是这个。

36

如果您将Newtonsoft.Json库与ASP.NET一起使用来读取/反序列化,则可以在JSON内容中使用注释:

//“ name”:“ string”

//“ id”:int

要么

/* 这是一个

评论示例* /

PS:单行注释仅在6+版本的Newtonsoft Json中受支持。

对于开箱即用的人的补充说明:想不开用的我将JSON格式用于我制作的ASP.NET Web应用程序中的基本设置。我阅读了文件,并使用Newtonsoft库将其转换为设置对象,并在必要时使用它。

我更喜欢在JSON文件本身中编写有关每个设置的注释,并且我真的不在乎JSON格式的完整性,只要我使用的库可以。

我认为这比创建单独的“ settings.README”文件并解释其中的设置“更易于使用/理解”。

如果您对这种用法有疑问;抱歉,精灵没电了。人们会发现JSON格式还有其他用法,您对此无能为力。


很难理解为什么有人在陈述事实时会遇到问题。
dvdmn

我假设有人因为上面的不再是JSON或无效的JSON而例外。添加简短的免责声明也许会让人安心。

5
我完全同意您的意见,但是到目前为止,对于仅表示显而易见的非回答,有883个投票。意识形态纯净度高于有用的信息,对您而言如此。
约翰

关键是带有注释的文件不是JSON,许多JSON库将无法对其进行解析。可以随意在自己的程序中执行任何操作,但是带有注释的文件不是JSON。如果您认为是这样,那么人们将尝试使用他们选择的语言/库对其进行解析,并且它将失败。这就像询问您是否可以在XML中使用方括号而不是尖括号。您可以做任何您想做的事,但是它将不再是XML。
gman

32

JSON背后的想法是提供应用程序之间的简单数据交换。这些通常是基于Web的,并且语言是JavaScript。

它实际上并不允许这样的注释,但是,尽管将数据显然需要解析代码特别地忽略或处理,但将注释作为数据中的名称/值对之一传递肯定会起作用。

综上所述,JSON文件不应该包含传统意义上的注释。它应该只是数据。

访问JSON网站以获取更多详细信息。


17
JSON格式确实没有注释。我个人认为这是一个重大错误-使用xml将注释作为元数据(而非数据)作为注释是非常有用的。JSON规范的早期草案版本确实包含注释,但是由于某些原因,它们被删除了。:-/
StaxMan

4
@StaxMan之所以删除它们,正是因为人们开始将它们用作元数据。Crockford说,它破坏了格式设计的兼容性,我同意:如果您想要元数据,为什么不将其作为实际数据包括在内?用这种方式解析甚至更容易。
卡米洛·马丁

6
元数据属于元数据结构(例如HTML <meta>标记),而不属于注释。滥用元数据注释只是在没有真正的元数据构造的情况下使用的黑客手段。
Marnen Laibow-Koser 2011年

这正是删除它的原因:用作元数据的注释会破坏互操作性。您也应该只将元数据存储为JSON。
令人惊讶的2013年

1
尽管答案可能写得更早,但答案写得更好,建议更高,答案也基本相同。这就是生活。

29

我只是在配置文件中遇到此问题。我不想使用XML(冗长,图形化,丑陋,难以阅读)或“ ini”格式(无层次结构,没有真正的标准等)或Java“属性”格式(如.ini)。

JSON可以完成他们所能做的所有事情,但是它的冗长程度更低,更易被人阅读-并且解析器在许多语言中都很容易实现。这只是一棵数据树。但是带外注释通常是记录“默认”配置等的必要条件。配置绝不能是“完整文档”,而可以是需要时人类可读的保存数据树。

我猜一个人可以"#": "comment"为“有效” JSON使用。


4
对于配置文件,我建议使用YAML,而不是JSON。它(几乎)是更强大的JSON超集,但也支持更具可读性的构造,包括注释。
Marnen Laibow-Koser 2011年

1
与json相比,您认为有多少种语言支持YAML?
mmm 2012年

@Hamidam十几种语言都支持yaml:yaml.org-但您是正确的问有多少种内置支持,而无需第三方库依赖。看起来像Ruby 1.9.2一样。有人认识别人吗?哪些语言默认支持json?
nealmcb 2012年

5
YAML互操作是一个谎言:stackoverflow.com/questions/450399/…。如果您的本能是将JSON用于配置文件,请遵循它。
toolbear 2014年

这很旧,但是我相信使用#不是一个好主意。Json接近Javascript语法。Javascript支持两种类型的注释://和/ * ... * /如果我是我,我会坚持使用其中一种或两种类型的注释。
Pascal Ganaye

28

JSON本身不支持注释,但是您可以使用自己的解码器或至少预处理器来剥离注释,这非常好(只要您只是忽略注释并且不使用它们来指导您的应用程序应如何处理JSON数据)。

JSON没有评论。JSON编码器不得输出注释。JSON解码器可以接受和忽略注释。

注释绝不能用于传达任何有意义的内容。这就是JSON的目的。

cf:JSON规范的作者Douglas Crockford


4
Crockford后来写道:“假设您使用JSON保留要注释的配置文件。继续并插入所需的所有注释。然后将其通过JSMin传递给JSON解析器。” 有关更多信息,请参见@ kyle-simpson关于JSON.minify的答案。


27

JSON对于配置文件和其他本地用法非常有意义,因为它无处不在,并且比XML更简单。

如果人们有充分的理由反对在传递数据时在JSON中添加注释(无论是否有效),则可以将JSON分为两种:

  • JSON-COM:在线上的JSON,或在传递JSON数据时适用的规则。
  • JSON-DOC:JSON文档,或文件中或本地的JSON。定义有效JSON文档的规则。

JSON-DOC将允许注释,并且可能存在其他细微差别,例如处理空格。解析器可以轻松地从一种规格转换为另一种规格。

关于道格拉斯·克罗克福德(Douglas Crockford)在此问题上的评论(@Artur Czajka引用)

假设您正在使用JSON保留要注释的配置文件。继续并插入您喜欢的所有评论。然后将其通过JSMin传递给JSON解析器。

我们正在谈论一个通用的配置文件问题(跨语言/跨平台),而他正在使用JS特定实用程序进行回答!

确保特定于JSON的minify可以用任何语言实现,但要对此进行标准化,以使其在所有语言和平台的解析器中无处不在,因此人们不再浪费时间缺少该功能,因为他们有很好的用例,正在寻找问题所在。在线论坛,并让人们告诉他们这是一个坏主意,或者表明很容易实现从文本文件中剥离注释。

另一个问题是互操作性。假设您有一个库或API或任何与某些配置或数据文件相关联的子系统。并且可以从不同的语言访问该子系统。然后,您要告诉人们:顺便说一句,不要忘记在将JSON文件传递到解析器之前从JSON文件中删除注释!


无需分段JSON。带注释的JSON不再是JSON。但是用注释为JSON注释是完全可以接受的,只要您确保在解析或传输JSON之前将其删除即可。这样做绝对不是接收方的责任。

json5.org是json-doc的解决方案
Michael Freidgeim

24

如果您使用JSON5,则可以包含注释。


JSON5是对JSON的拟议扩展,旨在使人类更轻松地手工编写和维护。它通过直接从ECMAScript 5添加一些最小的语法功能来做到这一点。


5
你能补充一个例子吗?然后,您实际上可能需要那些多余的字符。
dgilperez

6
SO指南要求提供实际答案。仅链接的答案是不希望的。您可以查看准则stackoverflow.com/help/how-to-answer
dgilperez

2
SO由其用户主持。这意味着如果我有一个答案,可以提供一个答案,如果不遵循准则,我可以为您提供答案。这样一来,SO便成为了很好的资源。
dgilperez 2015年

22

Dojo Toolkit JavaScript工具箱(至少从1.4版开始)允许您在JSON中包含注释。注释可以是/* */格式。Dojo Toolkit通过dojo.xhrGet()调用使用JSON 。

其他JavaScript工具包可能会类似地工作。

在选择最终选项之前尝试使用备用数据结构(甚至数据列表)时,这可能会有所帮助。


4
不,不是这个。JSON没有评论。如果选择用注释注释JSON,请在解析或传输之前将其最小化。这不应该是接收方的责任。

2
我没有说JSON有注释。我的意思也不是暗示将它们包括在JSON中是适当的,尤其是在生产系统中。我说过,Dojo工具箱允许您添加它们,这是(至少是)事实。在您的测试阶段,有许多非常有用的用例。
大卫

1
提供注释,这是很糟糕的巫术,因此是无效的JSON,它dojo.xhrGet()通过接受来隐式鼓励。

我仍然投票赞成升级JSON规范以允许评论。我全心全意地在传输JSON之前缩小和剥离注释,但是没有任何能力以任何标准方式注释JSON,而不必在解析之前将其通过单独的实用程序传递,这似乎很愚蠢。我还使您无法在JSON配置文件上使用JSON编辑器,因为您的文件不是有效的JSON。
Craig

20

JSON不是框架协议。这是一种无语言格式。因此,未为JSON定义注释的格式。

正如许多人建议的那样,有一些技巧,例如重复键或_comment您可以使用的特定键。由你决定。


18

可以JSONP中添加注释,但不能在纯JSON中添加注释。我刚刚花了一个小时,试图使我的程序在Highcharts中使用此示例:http ://www.highcharts.com/samples/data/jsonp.php ? filename = aapl-c.json&callback =?

如果您点击链接,将会看到

?(/* AAPL historical OHLC data from the Google Finance API */
[
/* May 2006 */
[1147651200000,67.79],
[1147737600000,64.98],
...
[1368057600000,456.77],
[1368144000000,452.97]
]);

由于我的本地文件夹中有一个类似的文件,因此Same-origin策略没有问题,因此我决定使用纯JSON ...,当然,$.getJSON由于注释而导致失败。

最终,我只是向上面的地址发送了一个手动HTTP请求,并意识到内容类型是text/javascript因为JSONP返回纯JavaScript。在这种情况下,允许注释。但是我的应用程序返回content-type application/json,所以我不得不删除注释。


17

这是一个“可以”的问题。这是一个“是”答案。

不,您不应该使用重复的对象成员将旁通道数据填充到JSON编码中。(请参阅RFC中的 “对象内的名称应唯一”)。

是的,您可以在JSON 周围插入注释,然后将其解析出来。

但是,如果您想要一种将任意辅助数据插入和提取到有效JSON的方法,这是一个答案。我们利用JSON编码中数据的非唯一表示形式。这是允许的*在“空白之前或之后任何六个结构特征允许”下的RFC的第二节。

* RFC仅声明“在六个结构字符中的任何一个之前或之后允许空白”,没有明确提及字符串,数字,“ false”,“ true”和“ null”。在所有实现中都会忽略此遗漏。


首先,通过缩小规范化JSON:

$jsonMin = json_encode(json_decode($json));

然后将您的评论编码为二进制:

$hex = unpack('H*', $comment);
$commentBinary = base_convert($hex[1], 16, 2);

然后隐藏您的二进制文件:

$steg = str_replace('0', ' ', $commentBinary);
$steg = str_replace('1', "\t", $steg);

这是您的输出:

$jsonWithComment = $steg . $jsonMin;

1
RFC仅声明“在六个结构字符中的任何一个之前或之后允许空白”,没有明确提及字符串,数字,“ false”,“ true”,“ null”。在所有实现中都会忽略此遗漏。
William Entriken 2014年

1
为了提高注释密度,您是否不能将注释编码为三元编码,并使用空格,制表符和换行符进行替换?
克莱尔·尼尔森

不应该这样。请参阅显式包含的RFC 2119:必须:该词,或术语“必需”或“外壳”,表示该定义是规范的绝对要求。...应该:这个词或形容词“推荐”表示在特定情况下可能存在忽略特定项目的正当理由,但是在选择其他课程之前,必须理解并仔细权衡所有含义。
杰夫·K

很好的参考。反对使用重复键的更好理由是该标准的引号“当对象中的名称不是唯一的时,接收该对象的软件的行为是不可预测的”。现在我也明白了为什么标准不是“必须唯一”的原因,这使验证器变得更加简单,它只需要跟踪[和{,它不需要知道已经使用了哪些键。
威廉·恩崔肯

16

免责声明:这很傻

实际上,有一种添加注释并保持在规范内的方法(无需其他解析器)。但是,如果不进行任何形式的解析,它将不会导致人类可读的注释。

您可能会滥用以下内容:

在任何令牌之前或之后都可以使用无关紧要的空格。空格是以下一个或多个代码点的任意序列:字符列表(U + 0009),换行符(U + 000A),回车符(U + 000D)和空格(U + 0020)。

您可以滥用这种方式添加评论。例如:用标签开始和结束您的评论。在base3中编码注释,并使用其他空格字符表示它们。例如。

010212 010202 011000 011000 011010 001012 010122 010121 011021 010202 001012 011022 010212 011020 010202 010202

hello base three以ASCII表示),而不是0使用空格,对于1使用换行,对于2使用回车。

这只会给您留下很多不可读的空格(除非您制作一个IDE插件来对其进行实时编码/解码)。

由于明显的原因,我什至从未尝试过,您也不应该尝试。


12

我们正在strip-json-comments为我们的项目使用。它支持类似:

/*
 * Description 
*/
{
    // rainbows
    "unicorn": /* ❤ */ "cake"
}

只需npm install --save strip-json-comments按照以下方式安装和使用它:

var strip_json_comments = require('strip-json-comments')
var json = '{/*rainbows*/"unicorn":"cake"}';
JSON.parse(strip_json_comments(json));
//=> {unicorn: 'cake'}

请注意,json当包含这些适当注释时,不再是有效的JSON。
罗伊·普林斯

12

就我而言,我需要在JSON结构的输出之前使用注释进行调试。因此,我决定在HTTP标头中使用调试信息,以避免破坏客户端:

header("My-Json-Comment: Yes, I know it's a workaround ;-) ");

在此处输入图片说明


12

JSON本身不允许评论。推理是完全愚蠢的,因为您可以使用JSON 本身来创建注释,从而完全避免推理,并且完全没有理由完全加载解析器数据空间,以得到完全相同的结果和潜在问题,例如:JSON带有注释的文件。

如果尝试(使用///* */#例如)放入注释,则某些解析器将失败,因为这严格不在JSON规范之内。因此,您绝对不要那样做。

例如,在这里,我的图像处理系统保存了图像符号和一些与它们有关的基本格式化(注释)信息(在底部):

{
    "Notations": [
        {
            "anchorX": 333,
            "anchorY": 265,
            "areaMode": "Ellipse",
            "extentX": 356,
            "extentY": 294,
            "opacity": 0.5,
            "text": "Elliptical area on top",
            "textX": 333,
            "textY": 265,
            "title": "Notation 1"
        },
        {
            "anchorX": 87,
            "anchorY": 385,
            "areaMode": "Rectangle",
            "extentX": 109,
            "extentY": 412,
            "opacity": 0.5,
            "text": "Rect area\non bottom",
            "textX": 98,
            "textY": 385,
            "title": "Notation 2"
        },
        {
            "anchorX": 69,
            "anchorY": 104,
            "areaMode": "Polygon",
            "extentX": 102,
            "extentY": 136,
            "opacity": 0.5,
            "pointList": [
                {
                    "i": 0,
                    "x": 83,
                    "y": 104
                },
                {
                    "i": 1,
                    "x": 69,
                    "y": 136
                },
                {
                    "i": 2,
                    "x": 102,
                    "y": 132
                },
                {
                    "i": 3,
                    "x": 83,
                    "y": 104
                }
            ],
            "text": "Simple polygon",
            "textX": 85,
            "textY": 104,
            "title": "Notation 3"
        }
    ],
    "imageXW": 512,
    "imageYW": 512,
    "imageName": "lena_std.ato",
    "tinyDocs": {
        "c01": "JSON image notation data:",
        "c02": "-------------------------",
        "c03": "",
        "c04": "This data contains image notations and related area",
        "c05": "selection information that provides a means for an",
        "c06": "image gallery to display notations with elliptical,",
        "c07": "rectangular, polygonal or freehand area indications",
        "c08": "over an image displayed to a gallery visitor.",
        "c09": "",
        "c10": "X and Y positions are all in image space. The image",
        "c11": "resolution is given as imageXW and imageYW, which",
        "c12": "you use to scale the notation areas to their proper",
        "c13": "locations and sizes for your display of the image,",
        "c14": "regardless of scale.",
        "c15": "",
        "c16": "For Ellipses, anchor is the  center of the ellipse,",
        "c17": "and the extents are the X and Y radii respectively.",
        "c18": "",
        "c19": "For Rectangles, the anchor is the top left and the",
        "c20": "extents are the bottom right.",
        "c21": "",
        "c22": "For Freehand and Polygon area modes, the pointList",
        "c23": "contains a series of numbered XY points. If the area",
        "c24": "is closed, the last point will be the same as the",
        "c25": "first, so all you have to be concerned with is drawing",
        "c26": "lines between the points in the list. Anchor and extent",
        "c27": "are set to the top left and bottom right of the indicated",
        "c28": "region, and can be used as a simplistic rectangular",
        "c29": "detect for the mouse hover position over these types",
        "c30": "of areas.",
        "c31": "",
        "c32": "The textx and texty positions provide basic positioning",
        "c33": "information to help you locate the text information",
        "c34": "in a reasonable location associated with the area",
        "c35": "indication.",
        "c36": "",
        "c37": "Opacity is a value between 0 and 1, where .5 represents",
        "c38": "a 50% opaque backdrop and 1.0 represents a fully opaque",
        "c39": "backdrop. Recommendation is that regions be drawn",
        "c40": "only if the user hovers the pointer over the image,",
        "c41": "and that the text associated with the regions be drawn",
        "c42": "only if the user hovers the pointer over the indicated",
        "c43": "region."
    }
}

“原因”链接已损坏。有机会找到当前链接吗?
唐·哈奇

不幸的是,唐(Don)杀死了包含该帖子的社交媒体系统;我不知道原始海报从那里去了,如果有的话。我将杀死上面信息中的链接,以消除歧义。谢谢。
fyngyrz

推理并不愚蠢,您只是证明了这一点。将注释实现为标签可保留互操作性。这正是 Crockford希望将注释解析为标签的原因。现在,所有内容都只是一个标记,并且以相同的方式进行解析。
Dominic Cerisano

如果规范说明“以#开头的行是注释”,那么它将完全可互操作。就目前而言,注释都加载解析器空间,因为它们是有效的已解析项目,而不是被理解为注释,并且它们对于每个现有的.json文件而言都可以不同。而如果(例如)规范说“以#开头的行是注释”,则解析器可以跳过这些行而不进行解析(更快),并且不加载解析器空间(更好的内存利用率)。 .json中的注释,只有缺点。
fyngyrz

11

要将JSON项目切成几部分,请添加“虚拟评论”行:

{

"#############################" : "Part1",

"data1"             : "value1",
"data2"             : "value2",

"#############################" : "Part2",

"data4"             : "value3",
"data3"             : "value4"

}

15
您已经在JSON中模拟了INI文件结构。请放下你的金锤。
Artur Czajka

4
RFC表示“对象内的名称应唯一”。也看到这个人是有错误解析JSON像上面:stackoverflow.com/questions/4912386/...
威廉Entriken

如果您使用模式来验证JSON,则由于额外的字段,它可能会失败。
gregsdennis

1
如果您真的确定要在JSON中添加注释,则执行以下操作会更有意义:{ "comment-001":"This is where you do abc...", "comment-002":"This is where you do xyz..." } 这样可以保持名称唯一,并允许您添加所需的任何字符串值。这仍然是一个难题,因为注释不应成为JSON的一部分。作为另一种选择,为什么不在JSON之前或之后添加注释,而不在其中添加注释呢?
Jazimov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.