2012-03-15 28 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

実際に簡略化された簡略化されたコードを実行しましたか? –

+0

ありがとう、私はこれを掘り下げます。 – buschtoens

+1

多分、ストリームに奇妙な制御文字が含まれているかもしれません... 'data'は文字列か、すでに解析されたオブジェクト(または何か他のもの)ですか? –

答えて

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

+0

私の場合、すべての応答は '\ r \ n'で終了します。しかし、あなたは一般的に正しいので、私は通知を追加しました。 – buschtoens

+1

この問題が発生している場合は、より一般的な解決策をご希望の場合は、 JSON.parse(data.toString()。trim()); String.prototype.trimは、空白。 – Zack

2

私は同様の問題がありました。より一般的な解決法については、これも機能します。文字列の前後にあるすべての空白を取り除くので、特定の部分文字列の長さを行う必要はありません。

JSON.parse(data.trim()); 
関連する問題