Node.jsМодуль 4: HTTP и Express
Модуль http
Создание HTTP сервера на чистом Node.js
Цель урока
В этом уроке ты научишься:
- Создавать HTTP сервер
- Обрабатывать запросы и ответы
- Понимать HTTP протокол
Создание сервера
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Привет, мир!');
});
server.listen(3000, () => {
console.log('Сервер запущен на http://localhost:3000');
});Объект Request (req)
const server = http.createServer((req, res) => {
console.log('Метод:', req.method); // GET, POST, PUT, DELETE
console.log('URL:', req.url); // /path?query=value
console.log('Заголовки:', req.headers); // { host: 'localhost', ... }
res.end('OK');
});Парсинг URL
const { URL } = require('url');
const server = http.createServer((req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
console.log('Путь:', url.pathname); // /users
console.log('Query:', url.searchParams); // URLSearchParams
console.log('id:', url.searchParams.get('id'));
res.end('OK');
});Объект Response (res)
const server = http.createServer((req, res) => {
// Статус и заголовки
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.setHeader('X-Custom-Header', 'value');
// Или одной командой
res.writeHead(200, {
'Content-Type': 'application/json',
'X-Custom-Header': 'value'
});
// Тело ответа
res.write('Часть 1');
res.write('Часть 2');
res.end('Конец'); // Завершает ответ
});Маршрутизация
const server = http.createServer((req, res) => {
const { method, url } = req;
if (method === 'GET' && url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Главная страница</h1>');
}
else if (method === 'GET' && url === '/api/users') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify([{ id: 1, name: 'Иван' }]));
}
else if (method === 'POST' && url === '/api/users') {
// Обработка POST
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => {
const user = JSON.parse(body);
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ id: 2, ...user }));
});
}
else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Не найдено');
}
});Получение тела запроса
function getBody(req) {
return new Promise((resolve, reject) => {
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => {
try {
resolve(JSON.parse(body));
} catch {
resolve(body);
}
});
req.on('error', reject);
});
}
const server = http.createServer(async (req, res) => {
if (req.method === 'POST') {
const body = await getBody(req);
console.log('Тело:', body);
}
res.end('OK');
});Статические файлы
const http = require('http');
const fs = require('fs');
const path = require('path');
const MIME_TYPES = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'text/javascript',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg'
};
const server = http.createServer((req, res) => {
const filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url);
const ext = path.extname(filePath);
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
fs.readFile(filePath, (err, data) => {
if (err) {
res.writeHead(404);
res.end('Файл не найден');
return;
}
res.writeHead(200, { 'Content-Type': contentType });
res.end(data);
});
});HTTP клиент
const http = require('http');
// GET запрос
http.get('http://api.example.com/data', (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => console.log(JSON.parse(data)));
});
// POST запрос
const options = {
hostname: 'api.example.com',
port: 80,
path: '/users',
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => console.log(JSON.parse(data)));
});
req.write(JSON.stringify({ name: 'Иван' }));
req.end();Рекомендация
Для HTTP клиента лучше использовать fetch (Node 18+) или библиотеку axios.
Практика
Задание 1: Простой сервер
Задача: Создай сервер, который отвечает JSON на /api/status.
Решение:
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/api/status') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'ok', time: new Date() }));
} else {
res.writeHead(404);
res.end('Not Found');
}
});
server.listen(3000);Проверь себя
- Как получить метод HTTP запроса?
- Как установить заголовок ответа?
- Как получить тело POST запроса?