Странная ошибка JSON.parse() в node.js

Я получаю некоторые строковые JSON через TCP в файле node.js и хочу его проанализировать. Так что мой подход похож на это. Я сократил и упростил это, так что вам не нужно знать окружающую логику.

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)

Поэтому я подумал: "Что может быть не так с JSON-String. Давайте попробуем это напрямую. Не должно работать". Сюрприз Сюрприз! Это сработало. Почему это работает, когда я непосредственно ввожу строку?

3 ответа

Решение

Благодаря @ 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 @ Zack, это более общее исправление для удаления непреднамеренных пробелов:

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

У меня была похожая проблема. Для более общего решения это тоже будет работать. Он удаляет все пробелы до и после строки, поэтому вам не нужно указывать конкретную длину подстроки.

JSON.parse(data.trim());

Вместо того, чтобы слепо удалять последние 4 символа, я предлагаю удалить только оскорбительные символы:

socket.on("data", function(data) {
    console.log(data.toString()); // Shows the original stringified version
    console.log(JSON.parse(data.toString().replace('\r','').replace('\n',''))); // Trim the sequence "\r\n" off the end of the string
});
Другие вопросы по тегам