11

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

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

, jQuery 会将请求发送为

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

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

我非常感谢您的帮助!

4

4 回答 4

19

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

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

...应该意味着:

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

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

JSON 解析器将 JSON 文本转换为另一种表示形式。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 解析器在这里做的唯一非法的事情就是引发异常。

您最不想在生产代码中做的事情就是依赖奇怪的副案例。因此,您要做的最后一件事是行使形成名义上合法但实际上无用的 JSON 的权利。如果你想这样做,你将不得不手工去做——构建你自己的抽象语法树,你自己的解析器,你自己的生成器,为任何可能想要使用你的数据的人生成生成器......

于 2013-11-12T10:47:07.047 回答
3

具有重复键的 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。但这将是惊人的愚蠢。

于 2013-06-12T10:37:40.687 回答
0

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

于 2015-02-21T04:25:11.147 回答
0

如果您无法在源头更改源,那么将源更改为您至少可以使用的东西......

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

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

您现在有一个有效的 JSON 键/值对数组,它是 javascript 合法的。

于 2015-05-26T20:15:04.473 回答