如何在javascript中完全获取具有重复键的JSON

IT技术 javascript jquery html json
2021-03-17 07:34:22

我试图从 url 获取 JSON,但在响应对象中删除了重复的键。有没有办法在不删除重复键的情况下完全获取它?这是我的 js 代码

$('document').ready(function(){
    var s = $.getJSON("new.json");
    console.log(s);
});

以下是我的 new.json

{
"s": "wae",
"s": "asd"
}

但在控制台中我得到如下的 json 对象

responseJSON: Object
s: "asd"

提前致谢

5个回答

如果您无法更改服务器响应,对于简单的 JSON 数据,您可以像文本一样请求 json 并像字符串一样解析它:

var check = new RegExp('["\']([^\'"]*)[\'"][^:]*:[^"\']*["\']([^\'"]*)[\'"]',"g");
    $.ajax({
        url : "text.json",
        dataType : "text",
        success : function(data){
            var newData = {};
            data.replace(check,function(a,b,c){
                if(typeof newData[b] == "undefined"){
                    newData[b] = c;
                }else if(typeof newData[b] == "object"){
                    newData[b].push(c);
                }else{
                    var ca = newData[b];
                    newData[b] = [ca,c];                     
                }
                return a;
            });
            console.log(newData);
            console.log($.parseJSON(data));
        },
        error : function(e,a){
            console.log(e,a);
        }
    });

在这段代码中newData,你的 json 是:

{"s": ["wae","asd"]}

JSON 对象中的键应该是唯一的。否则,带有该值的最后一个键通常是请求该键时出现的键。具有相同的键也使得区分对象的属性变得更加困难。密钥的全部意义在于使其可访问和可用。

为了解决这个问题,您可以始终:

  1. 更改 JSON 中的键

  2. 更改 JSON 以包含数组

    {"s": ["wae","asd"]}

JavaScript 对象表示法 (JSON) 数据交换格式) (RFC7159)说:

对象内的名称应该是唯一的。

在这种情况下必须按照RFC 2119 中的规定来理解

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


RFC 7159 解释了为什么唯一键是好的: > 名称都是唯一的对象在某种意义上是可互操作的 > 接收该对象的所有软件实现都将同意 > 名称-值映射。当对象内的名称不 > 唯一时,接收此类对象的软件的行为是 > 不可预测的。许多实现仅报告姓氏/值对 >。其他实现报告错误或无法解析 > 对象,一些实现报告所有名称/值对,> 包括重复项。> > 已经观察到 JSON 解析库在是否 > 使对象成员的排序对调用 > 软件可见方面有所不同。行为不依赖于成员的实现 >
虽然这些都是很好的建议,但它实际上并没有回答问题。
2021-04-21 07:34:22
@Quentin 是的,但看起来他确实能够从示例中自己更改 JSON,与其尝试回答问题,我觉得尝试提出一种有助于实现的良好实践的想法也无妨一种解决方法。上面的答案对于评论来说也很大,并且会因缺乏格式而受到影响。
2021-05-03 07:34:22
我刚刚给出了一个样本。实际上我无法更改 JSON。我想知道是否可以在没有重复的情况下获取。从评论我猜这是不可能的。
2021-05-06 07:34:22
@昆汀,@Craicerjack 谢谢
2021-05-18 07:34:22

这是不可能的JSON.parse()我相信更现代的 ES 规范指出后续的键会覆盖较早的键。

但是,JSON 规范并没有禁止这样的 JSON。还有其他的解析器和序列化器可以从 JavaScript 中生成和使用这样的 JSON。例如,您可以使用 SAX 风格的 JSON 解析器clarinet

const clarinet = require('clarinet');

const parser = clarinet.parser();
const result = [];
parser.onkey = parser.onopenobject = k => {
    result.push({key: k, value: null});
};
parser.onvalue = v => {
    result[result.length - 1].value = v;
};
parser.write('{"a": "1", "a": "2"}').close();

console.log(result);
// [ { key: 'a', value: '1' }, { key: 'a', value: '2' } ]

如果您想知道如何require()从浏览器使用,请学习如何使用webpack

JSON 允许重复键,但 JavascriptObjects不允许。

因为键可以复制,这意味着 JSON 不能表示为基于键/值的字典,也不能直接转换为 Javascript Object

您必须“遍历”JSON 中的每个键/值对,然后根据需要对其进行处理。我不知道你想转换成什么结构,但只要它不是 Javascript Object,就可以了。例如,您可以遍历一个 JSON 对象并将值输出到可以重复“键”.ini.css文件。

JSON.parse()将不起作用,因为这将尝试解析为 Javascript Object,它不允许重复的键。如果密钥被重用,解决方案是简单地覆盖任何先前的值。但是,我们可以使用基于JSON.parse()工作方式的代码,而不是在 Javascript 上设置属性Object,您可以从那里拆分并应用您的自定义解决方案。

您可以修改像json2这样的完整 JSON 解析器,或者使用像clarinetOboe.js那样在密钥到达时流式传输密钥的解析器

您可以尝试使用给定的结构多次使用相同的密钥:

[
  {"s": "wae"},
  {"s": "asd"}
]

正如 Craicerjack 所建议的,您还可以使用单个键查找多个值的数组:

{"s": ["wae","asd"]}
谢谢阿文德。但我的问题是是否可以不更改 JSON。
2021-05-20 07:34:22