Node.jsМодуль 4: HTTP и Express
Обработка данных
JSON, формы, загрузка файлов
Цель урока
В этом уроке ты научишься:
- Обрабатывать JSON данные
- Работать с формами
- Загружать файлы
JSON данные
Получение JSON
const express = require('express');
const app = express();
// Включаем парсинг JSON
app.use(express.json({ limit: '10mb' }));
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'Name and email required' });
}
res.status(201).json({ id: 1, name, email });
});Отправка JSON
app.get('/api/data', (req, res) => {
// Автоматически устанавливает Content-Type: application/json
res.json({
success: true,
data: [1, 2, 3],
timestamp: new Date()
});
});Формы (URL-encoded)
// Включаем парсинг форм
app.use(express.urlencoded({ extended: true }));
app.post('/login', (req, res) => {
const { username, password } = req.body;
// Обработка данных формы
res.json({ username });
});HTML форма
<form action="/login" method="POST">
<input name="username" type="text" />
<input name="password" type="password" />
<button type="submit">Войти</button>
</form>Загрузка файлов (Multer)
Установка
npm install multerБазовая настройка
const multer = require('multer');
// Хранение в памяти
const upload = multer({ storage: multer.memoryStorage() });
// Хранение на диске
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueName = `${Date.now()}-${file.originalname}`;
cb(null, uniqueName);
}
});
const uploadDisk = multer({ storage });Один файл
app.post('/upload', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
console.log(req.file);
// {
// fieldname: 'file',
// originalname: 'photo.jpg',
// mimetype: 'image/jpeg',
// size: 12345,
// buffer: <Buffer ...> // если memoryStorage
// path: 'uploads/...' // если diskStorage
// }
res.json({ filename: req.file.originalname });
});Несколько файлов
// Несколько файлов в одном поле
app.post('/upload', upload.array('files', 10), (req, res) => {
console.log(req.files); // массив файлов
res.json({ count: req.files.length });
});
// Разные поля
app.post('/upload', upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'photos', maxCount: 5 }
]), (req, res) => {
console.log(req.files.avatar);
console.log(req.files.photos);
res.json({ success: true });
});Фильтрация файлов
const upload = multer({
storage: multer.diskStorage({
destination: 'uploads/',
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`);
}
}),
limits: {
fileSize: 5 * 1024 * 1024 // 5MB
},
fileFilter: (req, file, cb) => {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (allowedTypes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Invalid file type'), false);
}
}
});Валидация данных
С Joi
npm install joiconst Joi = require('joi');
const userSchema = Joi.object({
name: Joi.string().min(2).max(50).required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(18).max(120),
role: Joi.string().valid('user', 'admin').default('user')
});
app.post('/users', (req, res) => {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({
error: error.details[0].message
});
}
res.json(value);
});С express-validator
npm install express-validatorconst { body, validationResult } = require('express-validator');
app.post('/users',
body('email').isEmail().normalizeEmail(),
body('password').isLength({ min: 6 }),
body('name').trim().notEmpty(),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
res.json(req.body);
}
);Практика
Задание 1: Загрузка аватара
Задача: Создай endpoint для загрузки аватара пользователя.
Решение:
const multer = require('multer');
const path = require('path');
const avatarStorage = multer.diskStorage({
destination: 'uploads/avatars/',
filename: (req, file, cb) => {
const ext = path.extname(file.originalname);
cb(null, `avatar-${req.params.userId}${ext}`);
}
});
const uploadAvatar = multer({
storage: avatarStorage,
limits: { fileSize: 2 * 1024 * 1024 },
fileFilter: (req, file, cb) => {
if (file.mimetype.startsWith('image/')) {
cb(null, true);
} else {
cb(new Error('Only images allowed'), false);
}
}
});
app.post('/users/:userId/avatar',
uploadAvatar.single('avatar'),
(req, res) => {
res.json({ path: req.file.path });
}
);Проверь себя
- Как включить парсинг JSON в Express?
- Как ограничить размер загружаемого файла?
- Как валидировать email с Joi?