JSON.parse()导致错误:`SyntaxError:位于0的JSON中的意外标记

时间:2017-05-25 08:47:40

标签: javascript json node.js

我在Node.js中编写了我的第一个应用程序。我试图从一个文件中读取一些数据,其中数据以JSON格式存储。

我收到此错误:

  

SyntaxError:位于0的JSON中的意外标记

     

at Object.parse(native)

以下是代码的这一部分:

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

这是console.log输出(我检查了.json文件本身,它是相同的):

Read JSON file: {

    "addresses": []

}

在我看来,这似乎是一个正确的JSON。为什么JSON.parse()失败呢?

7 个答案:

答案 0 :(得分:13)

文件开头有一个奇怪的字符。

data.charCodeAt(0) === 65279

我建议:

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

答案 1 :(得分:4)

JSON.parse()不允许使用逗号。所以,你需要摆脱它:

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

您可以找到更多相关信息here

答案 2 :(得分:2)

尝试这样

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

因为BOM需要在读取文件之前设置编码。它已在github

中的nodejs存储库中发布

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

答案 3 :(得分:2)

可能是BOM [1]。 我通过使用UTF-8 + BOM保存内容为{"name":"test"}的文件进行了测试,并生成了相同的错误。

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

根据此处[[{3}}]的建议,您可以在致电JSON.parse()之前将其替换或删除。

例如:

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

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

您还可以使用Buffer.slice()删除前3个字节(对于UTF-8)。

答案 4 :(得分:2)

进一步解释@Luillyfe的答案:

啊哈! fs.readFileSync("data.json")返回一个Javascript对象!

编辑:以下内容不正确...但是总结了人们一开始的想法!

我经历过的是一个字符串。因此,如果文件另存为UTF-8 / ascii,可能不会有问题?从readFileSync返回的javascript对象将转换为字符串JSON.parse可以解析?无需调用JSON.stringify吗?

我正在使用Powershell保存文件。这似乎将文件另存为UTF-16(现在太忙无法检查)。因此我收到“ SyntaxError:意外令牌-JSON在位置0。”

但是,JSON.stringify(fs.readFileSync("data.json"))正确地将返回的文件对象解析为JSON可以解析的字符串。

对我来说,我的json文件内容如下所示(将其记录到控制台后):

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

似乎文件不会加载到字符串中……

存在错误(不会崩溃...而是将json文件转换为乱码!):

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

我似乎在任何地方都找不到。但是有道理!

编辑:嗯...该对象只是一个缓冲区。抱歉!

解决方案:

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

用法:

GetJson("data.json");

注意:我目前还不需要异步。如果可以使这个异步,请添加另一个答案!

答案 5 :(得分:0)

如TamusJRoyce所述,我最终使用util.TextDecoder类提出了一种健壮的方式来读取UTF-8(不带BOM)和UTF-8(不带BOM)。这是代码段,假设文件input.json是UTF-8(带有或不带有BOM),并且包含有效的JSON。

const fs = require('fs');
const util = require('util');

const rawdata = fs.readFileSync('input.json');
const textDecoder = new util.TextDecoder('utf-8');
const stringData = textDecoder.decode(rawdata);
const objects = JSON.parse(stringData);

答案 6 :(得分:0)

const fs = require('fs');
const myConsole = new console.Console(fs.createWriteStream('./output.json'));
myConsole.log(object);

这将创建一个输出文件,其中包含可以通过console.log(object)触发的所有输出。

这是将console.log()输出转换为文件的最简单方法。