Странная ошибка 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
});