这让我抓狂。我不知道为什么,但是当我使用文件系统 require('fs')
读取有效的 Json 文件时,出现错误:无效的 json。这是代码:
var fs = require('fs');
const FILE_NAME = './json.json'
/*
// This way it works!
var jsonData = require('./json.json')
console.log(jsonData);
*/
async function readFile(filePath){
return new Promise(function(resolve, reject){
fs.readFile(filePath, 'utf8', function(err, contents) {
if(err){
console.log("Cant read the file " + err);
reject(err)
}
else{
resolve(contents)
}
})
})
}
async function getNames(fileName){
readFile(fileName).then(function(data){
try {
console.log(`Type of data: ` + typeof data);
console.log("File data: " + data);
return JSON.parse(data);
} catch (error) {
throw new Error( "Invalid JSON: " + error);
}
}).then(function(data){
console.log(`FILE OBJECT: ` + data);
}).catch(function(err){
console.error(err);
})
}
getNames(FILE_NAME)
这是文件内容:
{
"name": "riko"
}
这是控制台输出:
Type of data: string
File data: {
"name": "riko"
}
Error: Invalid JSON: SyntaxError: Unexpected token in JSON at position 0
at C:\Users\rojer\Desktop\Node\test\main.js:31:13
我知道我可以使用var jsonData = require('./json.json')
,但是
- 我想知道它不起作用的原因。
- 如果 JSON 数据嵌入到常规文本文件中的某个位置会怎样?
好像有一些垃圾。
请帮忙。
最佳答案
这个:
Error: Invalid JSON: SyntaxError: Unexpected token in JSON at position 0 at C:\Users\rojer\Desktop\Node\test\main.js:31:13
tells us that there's an invisible character at the beginning of the file, probably a byte order mark (BOM), that require
is handling but your code isn't. If the file is really in UTF-8, that BOM will be \xEF\xBB\xBF
. Once read as UTF-8 into a JavaScript string, that will be the code point \u{FEFF}
(because JavaScript strings are UTF-16 [but tolerate invalid surrogate pairs]). Update: Your binary listing of it confirms that.
I can confirm that if I have a UTF-8 JSON file with a BOM, require
reads it and handles the BOM, but readFile
returns the contents of the with the BOM intact, which trips up JSON.parse
.
You can check for the BOM and strip it off, see ***
lines:
const UTF8_BOM = "\u{FEFF}"; // ***
async function getNames(fileName){
readFile(fileName).then(function(data){
try {
console.log(`Type of data: ` + typeof data);
if (data.startsWith(UTF8_BOM)) { // ***
data = data.substring(UTF8_BOM.length); // ***
}
console.log("File data: " + data);
return JSON.parse(data);
} catch (error) {
throw new Error( "Invalid JSON: " + error);
}
}).then(function(data){
console.log(`FILE OBJECT: ` + data);
}).catch(function(err){
console.error(err);
})
}
或者,如果您不希望其中有 BOM,这里有一个快速但肮脏的工具,用于在 UTF-8 文件上添加/删除 BOM:
const fs = require("fs");
const UTF8_BOM = "\u{FEFF}";
const actions = new Map([
["-a", addBOM],
["-r", removeBOM],
["-t", toggleBOM]
]);
main();
function main() {
const filename = process.argv[2];
const option = process.argv[3] || "-t";
const action = actions.get(option);
if (!filename) {
help();
return;
}
if (!action) {
console.error(`Invalid option ${option}`);
help();
return;
}
fs.readFile(filename, 'utf-8', (err, data) => {
if (err) {
console.error(`${filename}: Error reading file: ${err}`);
return;
}
const hasBOM = data.startsWith(UTF8_BOM);
action(filename, data, hasBOM);
});
}
function writeResult(filename, data, toggle, successMessage, failMessage) {
fs.writeFile(filename, data, "utf-8", (err) => {
if (err) {
console.error(`${filename}: ${failMessage}: ${err}`);
} else {
console.log(`${filename}: ${successMessage}${toggle ? " (toggled)" : ""}`);
}
});
}
function addBOM(filename, data, hasBOM, toggle) {
if (hasBOM) {
console.log(`${filename}: Already has a BOM`);
} else {
writeResult(filename, UTF8_BOM + data, toggle, "Added BOM", "Error adding BOM");
}
}
function removeBOM(filename, data, hasBOM, toggle) {
if (!hasBOM) {
console.log(`${filename}: Already doesn't have a BOM`);
} else {
writeResult(filename, data.substring(UTF8_BOM.length), toggle, "Removed BOM", "Error removing BOM");
}
}
function toggleBOM(filename, data, hasBOM) {
if (hasBOM) {
removeBOM(filename, data, hasBOM, true);
} else {
addBOM(filename, data, hasBOM, true);
}
}
function help() {
console.log("Usage: node utf8bomtoggle [filename] {options}");
console.log("{options} can be:");
console.log(" -t Toggle a BOM [default]");
console.log(" -a Add a BOM if not present");
console.log(" -r Remove a BOM if present");
}
关于javascript - 使用 "fs"读取 JSON 文件会抛出 "invalid json"Node.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55775900/