2013-06-12 52 views
10

我知道这听起来不可能,但我的老板告诉我,我必须发送一个JSON通过AJAX后调用jQuery必须有重复键。问题是,如果我写的东西是这样的:如何使用重复键动态生成JSON对象?

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

,jQuery将请求发送作为

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

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

我会真的很感谢你的帮助!

+7

[ “的对象内的名称应该是唯一的。”](http://www.ietf.org/rfc/rfc4627.txt)。问问你的老板他是否想要你在购买左手油漆刷时。 – Quentin

+3

如果jQuery发送数据为'someurl?key1 = value1&key2 = value4&key3 = value5'那么它不会发送JSON。 – Quentin

+0

如果查询字符串是需要包含同一个键​​的倍数的最终结果,则不要使用不允许使用的API来创建它。只需使用适合的日期结构(例如json +数组)就可以自己构建它。 – Yoshi

回答

15

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

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

...应该在哪里意味着:

3.应。这个词,或者是“推荐”的形容词,表示 可能存在某些特殊情况下可以忽略某个特定项目的有效理由,但是在选择不同的课程之前必须仔细权衡全部含义并且仔细权衡。

所以是的,基本上你可以做到这一点,是法律,但它也是一个坏主意。不同的JSON解码器可能会以不同的方式处理这种情况,或者以不可预知的方式处理。看看规范要求的解析器​​:

JSON解析器将JSON文本转换为另一种表示形式。A 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
  • "your JSON is bad and you should feel bad"

...或刚刚好老nasal daemons。从字面上看,JSON解析器在这里做的唯一不合法的事情是引发异常。

你想在你的产品代码做的最后一件事是依靠怪异侧的情况。所以你想要做的最后一件事是行使你的权利,形成名义上合法但实际上无用的JSON。如果你想做到这一点,你必须通过做手工 - 建立自己的抽象语法树,你自己的解析器,你自己的发电机,发电机组对于谁可能要消耗你的数据...任何人

+1

这是一个很好的答案,但是忽略了这个问题其实并不是真的关于JSON ... – lonesomeday

+0

@lonesomeday AFAICT URL的查询部分[基本上是任意的](http://tools.ietf.org/html /rfc3986#section-3.4),其'key = value&key = value'结构主要是约定,所以'?a = b&a = c'仍然是合法的。因此,从JSON到URL的转换不会是荒谬的或不可能的,但肯定你不会免费获得标准组件。 – badp

+1

关键是Javascript对象文字可能有重复的键,JSON可能有重复的键,而HTTP查询可能有重复的键,但是Javascript对象不能,也没有什么能改变它。正如我解释的那样,问题是关于Javascript对象,而不是JSON。 – lonesomeday

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。但那将是惊人的愚蠢。

+0

我知道,但我的老板告诉我要找到一种动态生成带有重复键的JSON对象的方法。我告诉他这是不可能的,但他不感兴趣! –

+4

@ Razvan-CatalinOlaru请他画两边的三角形! – lonesomeday

+1

这将是一个不错的主意! –

0

我只有当另一端的JSON解析器正确接受它时才会这样做,而不会丢失任何东西。如果你能证明它掉落的东西,那么你可以看看另一种解决方案(如使用数组,或用手产生JSON,或正确使用URL,你首先需要更好的测试案例为您的服务器。

0

如果您不能改变在源源,然后更改源到的东西,你至少可以工作...

解析JSON成的键值对的数组(不进键/值对的对象) 。

如果你有机会到JSON字符串你可以做到这一点很容易,只需用全部替换“”‘},{’和‘[’和‘]’包装的结果。

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

+0

在解析它之前编辑输入是非常容易出错的。你的想法会用'[{“x”:“a},{b”}]'替换'{“x”:“a,b”}'。 (它仍然是有效的JSON,但现在该字符串具有不同的值。) – dpercy