2012-03-15 77 views
4

我想通过node.js中的TCP检索一些字符串化的JSON,并且想要解析它。所以我的方法与此相似。我缩短并简化它,所以你不必知道周围的逻辑。node.js中的奇怪的JSON.parse()错误

socket.on("data", function(data) { 
    console.log(data.toString());    // Shows the original stringifyed version 
    console.log(JSON.parse(data.toString())); // Doesn't work 
}); 

完整的(美化)JSON是这样的。正如你所看到的,没有错误。

{ 
    "result": "success", 
    "source": "chat", 
    "success": { 
     "message": "test", 
     "time": 1331770513, 
     "player": "silvinci" 
    } 
} 

JSON.parse(data.toString())总是抛出我这个愚蠢的错误:

{"result":"success","source":"console","success":{"time":1331762264,"line":"20 
^ 
SyntaxError: Unexpected token { 
    at Object.parse (native) 
    at Socket.<anonymous> (/home/node/api.js:152:35) // irrelevant from here on 
    at Socket.emit (events.js:67:17) 
    at TCP.onread (net.js:347:14) 

所以我thougt:“怎么可能是错的JSON字符串让我们试它一试不应该工作。”惊喜,惊喜!有效。为什么直接输入字符串时会起作用?

+1

您是否真的运行了缩短和简化的代码? – 2012-03-15 01:40:02

+0

谢谢,我会深入研究这一点。 – buschtoens 2012-03-15 01:40:49

+1

也许这个流包含一些奇怪的控制字符...... data是一个字符串还是已经解析过的对象(或别的东西)? – 2012-03-15 01:40:56

回答

12

感谢@Felix Kling我发现了我的错误。过滤未转义的字符非常重要,特别是在字符串化的JSON之外。我并没有忽略串行化JSON之后的无形换行。

这是修复:

socket.on("data", function(data) { 
    console.log(data.toString());       // Shows the original stringified version 
    console.log(JSON.parse(data.toString().slice(0, -4))); // Trim the sequence "\r\n" off the end of the string 
}); 

请注意,这仅作品对我来说,因为我有一个非常特殊的情况。服务器始终以JSON行响应,终止于\r\n - 不是空白字符,而是字面上反斜杠r和反斜杠n。
您的代码可能(或可能)由于其他错误而失败。但是当你解析错误时,检查服务器的响应是一个很好的起点。

正如@Zack正确地指出,这是为了去除意外的空白更一般的解决办法:

JSON.parse(data.toString().trim()); 
+2

不知道上下文,无条件截断字符串似乎有点危险。也许你应该在切片之前为违规字符添加一个测试。 – MarkHu 2012-12-06 03:59:51

+0

在我的情况下,每个响应都以'\ r \ n'结束。但总的来说你是对的,所以我附加了一个通知。 – buschtoens 2012-12-08 18:09:09

+1

如果你看到这个问题,并希望更通用的解决方案使用类似于: 'JSON.parse(data.toString()。trim());' String.prototype.trim将删除前导和尾随空白。 – Zack 2016-03-24 16:18:07

2

我有一个类似的问题。对于更一般的解决方案,这也可以工作。它会在字符串前后删除所有空白字符,因此您不必执行特定的子字符串长度。

JSON.parse(data.trim());