Введение в JSON и его роль в JavaScript
JSON (JavaScript Object Notation) — это легковесный формат обмена данными, основанный на синтаксисе объектов JavaScript. Несмотря на своё происхождение, JSON стал универсальным стандартом для передачи структурированных данных между сервером и клиентом, а также для хранения конфигураций и обмена информацией в микросервисных архитектурах.
В среде Node.js работа с JSON является повседневной задачей: от чтения конфигурационных файлов до обработки ответов REST API. В этой статье мы подробно рассмотрим два ключевых метода — JSON.parse() и JSON.stringify(), а также разберём типичные ошибки и лучшие практики.
1. Парсинг JSON: метод JSON.parse()
Метод JSON.parse() преобразует строку в формате JSON в объект JavaScript. Это необходимо, когда вы получаете данные от сервера, из файла или из внешнего источника.
Базовый синтаксис
const jsonString = '{"name": "Анна", "age": 30, "isStudent": false}';
const user = JSON.parse(jsonString);
console.log(user.name); // "Анна"
console.log(user.age); // 30
Продвинутое использование: reviver-функция
Вторым аргументом JSON.parse() может принимать функцию-преобразователь (reviver), которая позволяет модифицировать значения в процессе парсинга. Это полезно для конвертации строковых дат в объекты Date или для валидации данных.
const jsonData = '{"date": "2024-01-15T10:30:00.000Z", "value": 42}';
const parsed = JSON.parse(jsonData, (key, value) => {
if (key === 'date') {
return new Date(value);
}
return value;
});
console.log(parsed.date instanceof Date); // true
console.log(parsed.date.toLocaleDateString()); // "15.01.2024"
Обработка ошибок парсинга
Некорректный JSON вызовет исключение SyntaxError. Всегда оборачивайте вызов JSON.parse() в блок try...catch:
function safeParse(jsonString) {
try {
return { data: JSON.parse(jsonString), error: null };
} catch (error) {
console.error('Ошибка парсинга JSON:', error.message);
return { data: null, error: error.message };
}
}
const result = safeParse('{"name": "Ошибка"}');
console.log(result.data.name); // "Ошибка"
2. Сериализация в JSON: метод JSON.stringify()
Метод JSON.stringify() выполняет обратную задачу — преобразует объект JavaScript в строку JSON. Это используется при отправке данных на сервер, сохранении состояния или логировании.
Базовый синтаксис
const user = {
name: 'Иван',
age: 25,
skills: ['JavaScript', 'Node.js']
};
const jsonString = JSON.stringify(user);
console.log(jsonString);
// {"name":"Иван","age":25,"skills":["JavaScript","Node.js"]}
Параметры форматирования
Третий аргумент JSON.stringify() позволяет задать отступы для читаемого вывода. Это особенно полезно при записи в файлы или отладке.
const config = {
server: { port: 3000, host: 'localhost' },
database: { host: 'db.example.com', port: 5432 }
};
// Компактный вывод
console.log(JSON.stringify(config));
// Читаемый вывод с отступами в 2 пробела
console.log(JSON.stringify(config, null, 2));
// {
// "server": {
// "port": 3000,
// "host": "localhost"
// },
// ...
// }
Фильтрация свойств с помощью replacer
Второй аргумент — массив или функция, определяющие, какие свойства включать в результирующую строку.
const user = {
id: 1,
name: 'Мария',
email: 'maria@example.com',
password: 'secret123',
role: 'admin'
};
// Исключаем конфиденциальные данные
const safeUser = JSON.stringify(user, ['id', 'name', 'email', 'role']);
console.log(safeUser);
// {"id":1,"name":"Мария","email":"maria@example.com","role":"admin"}
// Или с помощью функции-фильтра
const filteredUser = JSON.stringify(user, (key, value) => {
if (key === 'password') return undefined; // исключаем
return value;
});
3. Работа с JSON в файловой системе Node.js
В Node.js часто требуется читать и записывать JSON-файлы. Рассмотрим типичные сценарии.
Чтение JSON из файла
const fs = require('fs');
const path = require('path');
function readJSONFile(filePath) {
try {
const absolutePath = path.resolve(filePath);
const fileContent = fs.readFileSync(absolutePath, 'utf-8');
return JSON.parse(fileContent);
} catch (error) {
if (error.code === 'ENOENT') {
console.error('Файл не найден:', filePath);
} else {
console.error('Ошибка чтения JSON:', error.message);
}
return null;
}
}
const config = readJSONFile('./config.json');
console.log(config?.database?.host);
Запись JSON в файл
function writeJSONFile(filePath, data) {
try {
const jsonString = JSON.stringify(data, null, 2);
fs.writeFileSync(filePath, jsonString, 'utf-8');
console.log('Данные успешно записаны в файл:', filePath);
} catch (error) {
console.error('Ошибка записи JSON:', error.message);
}
}
const appSettings = {
appName: 'MyApp',
version: '1.0.0',
features: ['auth', 'api', 'logging']
};
writeJSONFile('./settings.json', appSettings);
Асинхронная работа с JSON
const fsPromises = require('fs').promises;
async function readJSONAsync(filePath) {
try {
const content = await fsPromises.readFile(filePath, 'utf-8');
return JSON.parse(content);
} catch (error) {
console.error('Асинхронная ошибка:', error.message);
throw error;
}
}
// Использование
(async () => {
try {
const data = await readJSONAsync('./data.json');
console.log('Загружено записей:', Object.keys(data).length);
} catch (err) {
// обработка
}
})();
4. Типичные ошибки и их решение
Ошибка: Unexpected token
Возникает, когда строка содержит невалидный JSON. Частые причины: одинарные кавычки вместо двойных,