【问题标题】:How To Parse A String Of Concatenated JSON In Browser?如何在浏览器中解析连接的 JSON 字符串?
【发布时间】:2016-08-04 00:48:09
【问题描述】:

我正在使用 Socket.IO 将数据移动到浏览器。发送的数据是一串 JSON 对象,到达浏览器后变成一大串 JSON。问题是,这个 JSON 不能被 JSON.parse() 解析,因为它不是“真正的”JSON。

数据结构可以是任意的,因此 RegEx 可能无法解决问题。而当前的设置只是暂时的。最终,这个 JSON 流将在服务器端进行预处理,因此不需要将流发送到浏览器,所以我想保留我现在拥有的 AJAX/Socket.IO 设置,而不是切换到JSON 流解析器,例如 OboeJS

我可以做些什么来解析这个串联的 JSON 字符串?

为清楚起见,JSON 将如下所示:

{"a":"A"}{"b":"B"}{"c":"C"}

我正在尝试以一种可以访问它们的方式解析它:

console.log(Object.a) //A
console.log(Object.b) //B
console.log(Object.c) //C

【问题讨论】:

  • 您想像收到 JSON 一样处理数据吗?您确定数据将始终采用{}{}{}{} 格式吗?
  • @Dropout 是的,我愿意。并且它将始终采用{}{}{}{} 的格式,因为它将连接 JSON,但这会简化它。每个 JSON 可能都有嵌套数据,例如 {{}{}}{}{}{};或者可能有类似{"a":"This is valid JSON}"}
  • 那不是 JSON。如果您有几个 JSON 只是连接在一起,您可以拆分它们并在数组上调用 JSON.parse,但如果您有类似 {{}{}}{{{}}{}{{}}}{{}你真的不能指望它被任何东西直接解析,因为很难将规则应用到这样的东西上。那只是垃圾输入数据。看起来你将不得不实现一些东西来翻译那些东西..
  • 内部对象是有效的 JSON 格式,对还是错?因为在 JSON 内的字符串末尾添加 } 不会使其无效。我不考虑正则表达式方法,所以这不是问题。
  • 恕我直言,这个问题应该在数据提供者方面解决。尝试与他们讨论数据的格式。如果他们连接这些对象,他们当然可以像正常人一样输出该数组。我经常遇到这个问题,所以我知道这很容易说,但往往不是通过与数据提供方协商很容易解决,祝你好运!

标签: javascript json parsing stream frontend


【解决方案1】:

在您的特定情况下,您可以使用 Array.prototype.reduce 将所有 JSON 对象合并为一个:

var unstructuredJson = '{"a":"A"}{"b":"B"}{"c":"C"}';
var jsonArray = "[" + unstructuredJson.split("}{").join("},{") + "]";
var objectArray = JSON.parse(jsonArray);

var result = objectArray.reduce(function(result, item) {
  Object.keys(item).forEach(function(propertyName) {
    result[propertyName] = item[propertyName];
  });

  return result;
}, {});


document.body.textContent = JSON.stringify(result);

OP 在一些评论中说:

[...] 每个 JSON 可能都有嵌套数据,例如 {{}{}}{}{}{}

那么,在这种情况下,上述方法就被打破了。

我的两分钱是,您应该在流式传输这些 JSON 对象时添加一些分隔符,这样生活会更轻松:您将能够轻松拆分父对象,您只需将 split("}{") 更改为整个分隔器。

我建议你使用一些永远不会出现的字符作为任何属性值的一部分。您可以在此 Wikipedia 文章中找到控制字符:Control character

【讨论】:

  • @RobG 你的意思是无效的 JSON 吗?
  • 完全正确.. 可能类似于 JSON.parse(data.split("}{").join("},{")),但内部对象需要是您提到的有效 JSON..
  • @Dropout 可能 OP 已经手动完成了一些示例 JSON,并且实际的 JSON 是有效的......顺便说一句,如果 OP 没有发送有效的 JSON,他/她应该从修复这个问题开始否则 OP 将需要创建一个新的非 JSON 解析器...
  • @RobG 让我们看看 OP 说了什么......无论如何,正如我在之前的评论中所说,OP 需要调整代码和整个流式字符串以获得所需的结果,而无需重新发明轮子...我会期待OP的cmets...
  • 抱歉,我已将示例更新为有效的 JSON。是的,它实际上是有效的 JSON,但示例是手动完成的。
【解决方案2】:

如果每个子字符串都是有效的 JSON 但连接的部分不是,您可以将字符串转换为有效的数组字面量并使用 JSON.parse,然后您可以使用 Array 方法处理每个对象,例如forEach

var s = '{"a":"A"}{"b":"B"}{"c":"C"}';
var obj = JSON.parse('[' + s.replace(/}{/g,'},{') + ']').forEach(function (obj) {
  document.write(JSON.stringify(obj) + '<br>');
});

或者如果你想要它作为一个单独的对象:

var s = '{"a":"A"}{"b":"B"}{"c":"C"}';
var obj = JSON.parse(s.replace(/}{/g,','));

document.write(JSON.stringify(obj));

【讨论】:

    【解决方案3】:

    您可以使用 JsonParser 来解析连接的 json 对象:

        ObjectMapper mapper = new ObjectMapper();
        JsonFactory factory = new JsonFactory(mapper);
    
        JsonParser parser = factory.createParser(YourJsonString);
        List<YourObject> YourObjectList = new ArrayList<>();
    
        Iterator<YourObject> iterator = parser.readValuesAs(YourObject.class);
        while(iterator.hasNext()) {
            YourObject yourObject = iterator.next();
            loginSignalsList.add(yourObject);
        }
    

    【讨论】:

      【解决方案4】:

      拆分大字符串{a:'A'}{b:'B'}{c:'C'}并单独解析它们

      【讨论】:

        猜你喜欢
        • 2021-02-24
        • 1970-01-01
        • 1970-01-01
        • 2012-01-21
        • 2021-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-20
        相关资源
        最近更新 更多