web-dev-qa-db-fra.com

JSON.parse () provoque l'erreur suivante: `SyntaxError: jeton inattendu dans JSON à la position 0`

J'écris ma première application dans Node.js. J'essaie de lire des données à partir d'un fichier dans lequel les données sont stockées au format JSON. 

Je reçois cette erreur:

SyntaxError: jeton inattendu dans JSON à la position 0

à Object.parse (natif)

Voici cette partie du code:

//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);

Voici la sortie console.log (et j'ai vérifié le fichier .json lui-même, c'est la même chose):

Read JSON file: {

    "addresses": []

}

Cela me semble être un bon JSON. Pourquoi JSON.parse() échoue-t-il alors?

4
K48

JSON.parse() n'autorise pas les virgules. Donc, vous devez vous en débarrasser:

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

Vous pouvez trouver plus à ce sujet ici .

3
Luillyfe

essayez comme ça

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

c'est parce que la nomenclature nécessite le codage avant la lecture du fichier. sa été publié dans le référentiel de nodejs dans github

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

2
Mp de la Vega

Il s’agit peut-être de la nomenclature [ 1 ] .J'ai fait un test en enregistrant un fichier avec le contenu {"name":"test"} avec UTF-8 + BOM, et il a généré la même erreur.

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

Et sur la base d'une suggestion ici [ 2 ], vous pouvez le remplacer ou le supprimer avant d'appeler JSON.parse().

Par exemple:

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());
    }
});

ou

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());
    }
})

Vous pouvez également supprimer les 3 premiers octets (pour UTF-8) en utilisant Buffer.slice().

2
Aria Ax

Pour expliquer plus en détail la réponse de Luillyfe:

Ah-ha! fs.readFileSync("data.json") renvoie un objet Javascript!

Edit: Ci-dessous est incorrect ... Mais résume ce que l'on pourrait penser au premier abord!  

J'ai traversé c'était une ficelle. Donc, si le fichier était enregistré au format UTF-8/ascii, il n’aurait probablement pas de problème? L'objet javascript renvoyé par readFileSync serait converti en une chaîne que JSON.parse peut analyser? Pas besoin d'appeler JSON.stringify?

J'utilise powershell pour enregistrer le fichier. Ce qui semble enregistrer le fichier au format UTF-16 (trop occupé pour le moment). Je reçois donc "SyntaxError: Jeton inattendu en JSON en position 0."

Cependant, JSON.stringify(fs.readFileSync("data.json")) analyse correctement le fichier objet renvoyé dans une chaîne que JSON peut analyser.

Pour moi, le contenu de mon fichier json ressemble à celui ci-dessous (après l'avoir connecté à la console):

�{ " 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 "
         }
}

Cela ne semble pas être quelque chose qu'un fichier chargerait dans une chaîne ...

Être incorrect (cela ne plante pas ... mais convertit le fichier json en jibberish!):

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

Je n'arrive pas à trouver ça nulle part. Mais c'est logique!

Edit: Um ... Cet objet est juste un tampon. Toutes mes excuses pour ce qui précède!

Solution:

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);
}

Usage:

GetJson("data.json");

Remarque: je n'ai pas encore besoin que cela soit asynchrone. Ajoutez une autre réponse si vous pouvez rendre cela async!

1
TamusJRoyce