Javascript JSON.parse() 导致错误:`SyntaxError: Unexpected token in JSON at position 0`
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44176194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSON.parse() causes error: `SyntaxError: Unexpected token in JSON at position 0`
提问by bluehipy
I'm writing my first application in Node.js. I am trying to read some data from a file where the data is stored in the JSON format.
我正在用 Node.js 编写我的第一个应用程序。我正在尝试从数据以 JSON 格式存储的文件中读取一些数据。
I get this error:
我收到此错误:
SyntaxError: Unexpected token ? in JSON at position 0
at Object.parse (native)
语法错误:意外的令牌?在位置 0 处的 JSON
在 Object.parse(本机)
Here is this part of the 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);
Here is the console.logoutput (and I checked the .json file itself, it's the same):
这是console.log输出(我检查了 .json 文件本身,它是一样的):
Read JSON file: ?{
"addresses": []
}
That seems to me like a correct JSON. Why does JSON.parse()fail then?
在我看来,这就像一个正确的 JSON。那为什么会JSON.parse()失败呢?
回答by bluehipy
You have a strange char at the beginning of the file.
文件开头有一个奇怪的字符。
data.charCodeAt(0) === 65279
data.charCodeAt(0) === 65279
I would recommend:
我会推荐:
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);
}});
回答by Luillyfe
回答by Netorica
try it like this
像这样试试
fs.readFile('addresses.json','utf-8', function (err, data) {
if (data) {
console.log("Read JSON file: " + data);
storage = JSON.parse(data);
its because of the BOM that needs an encoding to be set before reading the file. its been issued in nodejs respository in github
这是因为在读取文件之前需要设置编码的 BOM。它已在 github 的 nodejs 存储库中发布
回答by Aria Ax
It might be the BOM[1].
I have done a test by saving a file with content {"name":"test"}with UTF-8 + BOM, and it generated the same error.
它可能是 BOM[ 1]。我已经通过保存{"name":"test"}带有 UTF-8 + BOM内容的文件进行了测试,它生成了相同的错误。
> JSON.parse(fs.readFileSync("a.json"))
SyntaxError: Unexpected token in JSON at position 0
And based on a suggestion here [2], you can replace it or drop it before you call JSON.parse().
根据此处 [ 2]的建议,您可以在致电之前更换或丢弃它JSON.parse()。
For example:
例如:
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());
}
});
or
或者
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());
}
})
You can also remove the first 3 bytes (for UTF-8) by using Buffer.slice().
您还可以使用Buffer.slice().
回答by TamusJRoyce
To further explain @Luillyfe's answer:
进一步解释@Luillyfe的回答:
Ah-ha! fs.readFileSync("data.json")returns a Javascript object!
啊哈!fs.readFileSync("data.json")返回一个 Javascript 对象!
Edit: Below is incorrect...But summarizes what one might think at first!
编辑:下面是不正确的......但总结了人们一开始可能会想到的!
I had through that was a string. So if the file was saved as UTF-8/ascii, it would probably not have an issue? The javascript object returned from readFileSync would convert to a string JSON.parse can parse? No need to call JSON.stringify?
我经历过那是一个字符串。所以如果文件被保存为 UTF-8/ascii,它可能不会有问题?从 readFileSync 返回的 javascript 对象将转换为字符串 JSON.parse 可以解析?不需要调用 JSON.stringify?
I am using powershell to save the file. Which seems to save the file as UTF-16 (too busy right now to check). So I get "SyntaxError: Unexpected token ? in JSON at position 0."
我正在使用 powershell 来保存文件。这似乎将文件保存为 UTF-16(现在太忙无法检查)。所以我得到“SyntaxError: Unexpected token ? in JSON at position 0.”
However, JSON.stringify(fs.readFileSync("data.json"))correctly parses that returned file object into a string JSON can parse.
但是,JSON.stringify(fs.readFileSync("data.json"))正确地将返回的文件对象解析为字符串 JSON 可以解析。
Clue for me is my json file contents looking like the below (after logging it to the console):
我的线索是我的 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 "
}
}
That doesn't seem like something a file would load into a string...
这似乎不像文件会加载到字符串中的东西......
Incorrect being (this does not crash...but instead converts the json file to jibberish!):
不正确(这不会崩溃……而是将 json 文件转换为乱码!):
const jsonFileContents = JSON.parse(JSON.stringify(fs.readFileSync("data.json")));
I can't seem to find this anywhere. But makes sense!
我似乎无法在任何地方找到这个。不过有道理!
Edit: Um... That object is just a buffer. Apologies for the above!
编辑:嗯...那个对象只是一个缓冲区。对以上内容表示歉意!
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");
Note: I don't currently have a need for this to be async yet. Add another answer if you can make this async!
注意:我目前还不需要它是异步的。如果您可以使此异步,请添加另一个答案!
回答by user3478739
As mentioned by TamusJRoyce I ended up using the util.TextDecoder class to come up with a robust way to read both UTF-8 (without BOM) and UTF-8 (with BOM). Here's the snippit, assuming that file input.json is UTF-8 (with or without BOM) and contains valid JSON.
正如 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);
回答by Avinash Chandravansi
const fs = require('fs');
const myConsole = new console.Console(fs.createWriteStream('./output.json'));
myConsole.log(object);
This will create an output file with all the output which can been triggered through console.log(object).
这将创建一个输出文件,其中包含可以通过console.log(object).
This is the easiest way to convert the console.log()output into a file.`
这是将console.log()输出转换为文件的最简单方法。`

