如何在JS中解析流上的第一个JSON对象 [英] How can I parse the first JSON object on a stream in JS

查看:203
本文介绍了如何在JS中解析流上的第一个JSON对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JSON对象流,就像TCP或WebSockets上的JSON-RPC一样。没有长度前缀或分隔符,因为JSON是自我分隔的。所以,当我从流中读到时,我可能会得到这样的结果:

I have a stream of JSON objects, as with JSON-RPC over TCP or WebSockets. There's no length prefix or delimiter, because JSON is self-delimiting. So, when I read from the stream, I may end up with something like this:

{"id":1,"result":{"answer":23},"error":null}
{"id":2,"result":{"answer":42},"error":null}
{"id":3,"result":{"answ

我需要解析每个JSON对象我不能用JSON.parse做到这一点,因为它只会在最后为无关数据抛出语法错误。

I need to parse each JSON object one by one. I can't do this with JSON.parse, because it will just throw a syntax error for extraneous data at the end.

当然这个例子我可以逐行进行,但我不能依赖看起来像这样的空白; JSON-RPC可以很容易看起来像这样:

Of course with that example I could go line by line, but I can't rely on the whitespace looking like that; JSON-RPC can just as easily look like this:

{
  "id": 1, 
  "result": {
    "answer": 23
  },
  "error":null
} 

或者这个:

{"id":1,"result":{"answer":23},"error":null}{"id":2,"result":{"answer":42},"error":null}

对于大多数其他语言的解析器,显而易见的答案是像这样的东西(使用Python作为示例):

With most parsers in other languages, the obvious answer is something like this (using Python as an example):

buf = ''
decoder = json.JSONDecoder()
def onReadReady(sock):
  buf += sock.read()
  obj, index = decoder.raw_decode(buf)
  buf = buf[index:]
  if obj:
    dispatch(obj)

但我在JS中找不到类似的东西。我查看了我能找到的每个JS解析器,它们都有效地等同于JSON.parse。

But I can't find anything similar in JS. I've looked at every JS parser I can find, and they're all effectively equivalent to JSON.parse.

我试着查看各种JSON-RPC框架来查看他们如何处理这个问题,他们只是没有。他们中的许多人都认为recv总是会返回一个send(这对于JSON-RPC通过HTTP工作正常,但不适用于TCP或WebSockets - 当然,它可能在本地测试中起作用)。其他人实际上并没有处理JSON-RPC,因为他们在空格上添加了一些要求(其中一些甚至对JSON-RPC都没有效)。

I tried looking at various JSON-RPC frameworks to see how they handle this problem, and they just don't. Many of them assume that a recv will always return exactly one send (which works fine for JSON-RPC over HTTP, but not over TCP or WebSockets—although it may appear to work in local tests, of course). Others don't actually handle JSON-RPC because they add requirements on whitespace (some of which aren't even valid for JSON-RPC).

我可以写一个分隔符检查是否平衡括号和引号(当然是处理转义和引用),或者只是从头开始编写JSON解析器(或从另一种语言编写端口1,或修改 http://code.google.com/p/json-sans-eval/ ),但我无法相信没有人这样做过之前。

I could write a delimiter check that balances brackets and quotes (handling escaping and quoting, of course), or just write a JSON parser from scratch (or port one from another language, or modify http://code.google.com/p/json-sans-eval/), but I can't believe no one has done this before.

编辑:我自己制作了两个版本, http ://pastebin.com/fqjKYiLw 基于json-sans-eval和 http://pastebin.com / 8H4QT82b 基于Crockford的参考递归下降解析器json_parse.js。我仍然更喜欢使用经过其他人测试和使用的东西,而不是自己编写代码,所以我将这个问题保持开放。

I've made two versions myself, http://pastebin.com/fqjKYiLw based on json-sans-eval, and http://pastebin.com/8H4QT82b based on Crockford's reference recursive descent parser json_parse.js. I would still prefer to use something that's been tested and used by other people rather than coding it myself, so I'm leaving this question open.

推荐答案

经过一个月的搜索替代方案而没有找到任何有用的东西,我决定编写一堆不同的实现并测试它们,然后我修改了Crockford的参考递归下降解析器(如下所述)问题,此处可用)。

After a month of searching for alternatives and not finding anything useful, I decided to code up a bunch of different implementations and test them out, and I went with my modification of Crockford's reference recursive-descent parser (as described in the question, available here).

这不是最快的,但在我做的每一项测试中它都足够快。更重要的是,它可以捕获明显错误的JSON,当它与不完整的JSON不一致时,比大多数其他替代方案要好得多。最重要的是,它需要从众所周知且经过验证的代码库中进行非常简单的更改,这使我对其正确性更有信心。

It wasn't the fastest, but it was more than fast enough in every test I did. More importantly, it catches clearly erroneous JSON, when that's not ambiguous with incomplete JSON, much better than most of the other alternatives. Most importantly, it required very few, and pretty simple, changes from a well-known and -tested codebase, which makes me more confident in its correctness.

仍然,如果任何人都知道有一个比我更好的图书馆(只是被许多项目使用而不仅仅是我认为是一个重要的资格),我很想知道它。

Still, if anyone knows of a better library than mine (and just being used by lots of projects instead of just me would count as a major qualification), I'd love to know about it.

这篇关于如何在JS中解析流上的第一个JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆