web-dev-qa-db-de.com

JSON.parse () verursacht Fehler: `SyntaxError: Unerwartetes Token in JSON an Position 0`

Ich schreibe meine erste Anwendung in Node.js. Ich versuche, einige Daten aus einer Datei zu lesen, in der die Daten im JSON-Format gespeichert sind. 

Ich erhalte diesen Fehler:

SyntaxError: Unerwartetes Token in JSON an Position 0

bei Object.parse (native)

Hier ist dieser Teil des Codes:

//read saved addresses of all users from a JSON file
fs.readFile('addresses.json', function (err, data) {
    if (data) {
        console.log("Read JSON file: " + data);
        storage = JSON.parse(data);

Hier ist die console.log-Ausgabe (und ich habe die .json-Datei selbst geprüft, es ist dasselbe):

Read JSON file: {

    "addresses": []

}

Das scheint mir ein richtiger JSON zu sein. Warum versagen dann JSON.parse()?

4
K48

Sie haben ein seltsames Zeichen am Anfang der Datei.

data.charCodeAt(0) === 65279

Ich würde empfehlen:

fs.readFile('addresses.json', function (err, data) {
if (data) {
    console.log("Read JSON file: " + data);
    data = data.trim(); 
    //or data = JSON.parse(JSON.stringify(data.trim()));
    storage = JSON.parse(data);
 }});
11
bluehipy

JSON.parse() erlaubt keine abschließenden Kommas. Also musst du es loswerden:

JSON.parse(JSON.stringify(data));

Mehr dazu finden Sie hier hier .

3
Luillyfe

probier es so aus

fs.readFile('addresses.json','utf-8', function (err, data) {
    if (data) {
        console.log("Read JSON file: " + data);
        storage = JSON.parse(data);

dies liegt an der Stückliste, für die vor dem Lesen der Datei eine Codierung festgelegt werden muss. es wurde in nodejs respository in github ausgegeben

https://github.com/nodejs/node-v0.x-archive/issues/186

2
Mp de la Vega

Möglicherweise handelt es sich um die Stückliste [ 1 ] . Ich habe einen Test durchgeführt, indem ich eine Datei mit dem Inhalt {"name":"test"} mit UTF-8 + BOM gespeichert habe, und der gleiche Fehler wurde generiert.

> JSON.parse(fs.readFileSync("a.json"))
SyntaxError: Unexpected token  in JSON at position 0

Und basierend auf einem Vorschlag [ 2 ] können Sie ihn ersetzen oder löschen, bevor Sie JSON.parse() aufrufen.

Zum Beispiel:

var storage = {};

fs.readFile('a.json', 'utf8', function (err, data) {
    if (data) {
        console.log("Read JSON file: " + data);
        console.log(typeof(data))
        storage = JSON.parse(data.trim());
    }
});

oder

var storage = {};
fs.readFile('a.json', function (err, data) {
    if (data) {
        console.log("Read JSON file: " + data);
        console.log(typeof(data))
        storage = JSON.parse(data.toString().trim());
    }
})

Sie können die ersten 3 Bytes (für UTF-8) auch mit Buffer.slice() entfernen.

2
Aria Ax

Um die Antwort von @ Luillyfe weiter zu erklären:

Ah-ha! fs.readFileSync("data.json") gibt ein Javascript-Objekt zurück!

Edit: Unten ist falsch ... Aber fasst zusammen, was man zuerst denken könnte!  

Ich hatte dabei eine Saite. Wenn die Datei als UTF-8/ascii gespeichert wurde, hätte sie wahrscheinlich kein Problem? Das von readFileSync zurückgegebene Javascript-Objekt würde in eine Zeichenfolge konvertiert, die JSON.parse analysieren kann. Kein Aufruf von JSON.stringify?

Ich verwende Powershell, um die Datei zu speichern. Was scheint, die Datei als UTF-16 zu speichern (momentan zu beschäftigt, um sie zu überprüfen). Ich bekomme also "SyntaxError: Unerwartetes Token in JSON an Position 0".

JSON.stringify(fs.readFileSync("data.json")) analysiert jedoch korrekt, dass das zurückgegebene Dateiobjekt in einen String konvertiert wurde, den JSON analysieren kann.

Ein Hinweis für mich ist der Inhalt meiner json-Datei, der wie folgt aussieht (nachdem er an der Konsole angemeldet wurde):

�{ " R o o m I D _ L o o k u p " :   [
         {
                 " I D " :     1 0 ,
                 " L o c a t i o n " :     " f r o n t " ,
                 " H o u s e " :     " f r o n t r o o m "
         }
}

Das scheint nicht etwas zu sein, was eine Datei in einen String laden würde ...

Falsches Wesen (das stürzt nicht ab ... sondern konvertiert die Json-Datei in Jibberish!):

const jsonFileContents = JSON.parse(JSON.stringify(fs.readFileSync("data.json")));

Ich kann das nirgendwo finden. Aber macht Sinn!

Edit: Um ... Das Objekt ist nur ein Puffer. Entschuldigung für das oben!

Lösung:

const fs = require("fs");

function GetFileEncodingHeader(filePath) {
    const readStream = fs.openSync(filePath, 'r');
    const bufferSize = 2;
    const buffer = new Buffer(bufferSize);
    let readBytes = 0;

    if (readBytes = fs.readSync(readStream, buffer, 0, bufferSize, 0)) {
        return buffer.slice(0, readBytes).toString("hex");
    }   

    return "";
}

function ReadFileSyncUtf8(filePath) {
    const fileEncoding = GetFileEncodingHeader(filePath);
    let content = null;

    if (fileEncoding === "fffe" || fileEncoding === "utf16le") {
        content = fs.readFileSync(filePath, "ucs2"); // utf-16 Little Endian
    } else if (fileEncoding === "feff" || fileEncoding === "utf16be") {
        content = fs.readFileSync(filePath, "uts2").swap16(); // utf-16 Big Endian
    } else {
        content = fs.readFileSync(filePath, "utf8");
    }

    // trim removes the header...but there may be a better way!
    return content.toString("utf8").trimStart();
}

function GetJson(filePath) {
    const jsonContents = ReadFileSyncUtf8(filePath);
    console.log(GetFileEncodingHeader(filePath));

    return JSON.parse(jsonContents);
}

Verwendungszweck:

GetJson("data.json");

Hinweis: Ich habe derzeit noch keine Notwendigkeit, dass dies asynchron ist. Fügen Sie eine weitere Antwort hinzu, wenn Sie dies asynchron machen können!

1
TamusJRoyce