如何使用重复键动态生成JSON对象?

我知道这听起来不可能,但我的老板告诉我,我必须通过jQuery发送一个JSON,jQuery必须有重复键。 问题是如果我写这样的东西:

$.post("someurl", { "key1" : "value1", "key2" : "value2", "key2" : "value3", "key2" : "value4", "key3" : "value5" }); 

,jQuery将发送请求为

 someurl?key1=value1&key2=value4&key3=value5 

这一切都是因为Javascript会覆盖具有相同名称的属性。 JSON对象是动态生成的,我不允许在其中使用数组。 有人能告诉我如何生成JSON对象dinamicaly和重复键?

我真的很感谢你的任何帮助!

从我所看到的,根据RFC 4627 , {"a": "b", "a": "c"}实际上是有效的 JSON。

对象结构表示为围绕零个或多个名称/值对(或成员)的一对花括号。 名称是一个字符串。 每个名称后面都有一个冒号,将名称与值分开。 单个逗号将值与以下名称分隔开。 对象中的名称应该是唯一的。

……应该在哪里:

3.应该。 这个词,或形容词“推荐”,意味着在特定情况下可能存在忽略特定项目的正当理由,但在选择不同的课程之前必须理解并仔细权衡全部含义。

所以,是的,基本上你可以做到这一点,这是合法的 ,但这也是一个坏主意。 不同的JSON解码器可能会以不同的方式和/或以不可思议的方式处理这种情况。 看一下规范对解析器的要求:

JSON解析器将JSON文本转换为另一种表示forms。 JSON解析器必须接受符合JSON语法的所有文本。 JSON解析器可以接受非JSON表单或扩展。

实现可以对其接受的文本大小设置限制。 实现可以设置最大嵌套深度的限制。 实现可以对数字范围设置限制。 实现可以对字符串的长度和字符内容设置限制。

…但是实现不必处理这样的情况。 例如:

 # Python 2.7 >>> import json >>> json.JSONDecoder().decode('{"a": "b", "a": "c"}') `{u'a': u'c'}` # Chrome 32 > JSON.parse('{"a": "b", "a": "c"}') Object {a: "c"} 

…和其他实现可能合法地给你(用Python表示法):

  •   {“a”:“b”} 
  •   [(“a”,“b”),(“a”,“c”)] 
  •   [(“a”,[“b”,“c”])] 
  •   [] 
  •   42 
  •   “你的JSON很糟糕,你应该心疼” 

……或者只是好老的鼻子守护进程 。 从字面上看,JSON解析器在这里做的唯一非法事情是引发exception。

您想要在生产代码中做的最后一件事是依赖于奇怪的边案例。 所以你要做的最后一件事是行使你的权利,形成名义上合法但实际上无用的JSON。 如果你想这样做,你必须手工完成 – 为任何可能想要使用你的数据的人建立你自己的抽象语法树,你自己的解析器,你自己的生成器,生成器……

具有重复键的Javascript对象不是Javascript对象。 事实上,它只不过是你想象中的一个虚构。 这完全不可能。

唯一的方法是使用数组:

 { "key1" : "value1", "key2" : ["value2", "value3", "value4"], "key3" : "value5" } 

jQuery会将其转换为key1=value1&key2%5B%5D=value2&key2%5B%5D=value3&key2%5B%5D=value4&key3=value5

这确实是实现此目的的唯一方法。*您的代码无法生成有效的JSON吗?

*除了编写自己的解析器来处理无效的JSON。 但那将是令人惊讶的愚蠢。

只有当另一方的JSON解析器正确接受它而不丢弃任何东西时,我才会这样做。 如果您可以显示它丢弃的东西,那么您可以寻找另一种解决方案(例如使用数组,或手动生成JSON,或正确使用URL。您需要首先为您的服务器提供更好的测试用例。

如果您无法在源代码中更改源代码,请将源代码更改为至少可以使用的内容…

将JSON解析为键值对数组(而不是键/值对的对象)。

如果您可以访问JSON字符串,只需将所有“,”替换为“},{”并将结果包装在“[”和“]”中,就可以轻松完成此操作。

您现在拥有一个有效的JSON合法的键/值对数组。