小编典典

如何解析JS流中的第一个JSON对象

json

我有一个JSON对象流,就像通过TCP或WebSockets的JSON-
RPC一样。没有长度前缀或定界符,因为JSON是自定界的。因此,当我从流中读取内容时,可能会遇到如下所示的结果:

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

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

当然,在这个示例中,我可以逐行进行,但是我不能依赖像这样的空白。JSON-RPC看起来就像这样:

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

或这个:

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

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

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。

我尝试查看各种JSON-RPC框架以了解它们如何处理此问题,而实际上却没有。他们中的许多人都认为recv将始终只返回一个发送(这对于通过HTTP的JSON-
RPC正常工作,但对于通过TCP或WebSocket的JSON-RPC则工作正常,尽管它当然可以在本地测试中工作)。其他人实际上不处理JSON-
RPC,因为它们在空白上添加了要求(其中某些要求甚至对JSON-RPC无效)。

我可以编写定界符检查来平衡括号和引号(当然,要处理转义和引号),或者只是从头开始编写JSON解析器(或从另一种语言移植一个JSON解析器),或者修改http://code.google.com/p
/ json-sans-eval /),但我不相信以前没有人这样做过。

编辑:我已经做了两个版本的自己,http://pastebin.com/fqjKYiLw基于JSON的SAN-
EVAL和http://pastebin.com/8H4QT82b基于Crockford的参考递归下降解析器json_parse.js。我仍然更喜欢使用经过其他人测试和使用的东西,而不是自己编写代码,因此我将这个问题留待解决。


阅读 486

收藏
2020-07-27

共1个答案

小编典典

经过一个月的搜索,没有找到任何有用的东西之后,我决定编写一堆不同的实现并进行测试,然后我对Crockford的参考递归下降解析器进行了修改

它不是最快的,但是在我做的每项测试中都足够快。更重要的是,当不与不完整的JSON保持一致时,它可以捕获明显错误的JSON,这比大多数其他替代方法要好得多。最重要的是,它与著名且经过测试的代码库之间的更改非常少,而且非常简单,这使我对其正确性更有信心。

但是,如果有人知道比我的图书馆更好的图书馆(并且被很多项目而不是仅由我使用将被视为主要资格),我很想知道这一点。

2020-07-27