Отправка файлов с сервера
Отправка статических файлов — HTML, CSS, JS, изображений — это основа любого веб-сервера. NodeJS позволяет отдавать их через модуль fs (file system).
Статические файлы
Это файлы, которые не генерируются динамически — они лежат на диске и просто читаются и отправляются клиенту.
Пример структуры проекта:
project/
├── server.js
├── index.html
├── styles/
│ └── style.css
├── scripts/
│ └── app.js
└── images/
└── logo.png
Задача сервера:
- При запросе
/→ отдатьindex.html - При запросе
/styles/style.css→ отдатьstyle.css - При запросе
/images/logo.png→ отдатьlogo.png
Чтение файлов: fs.readFile()
Используем асинхронный метод fs.readFile() — он не блокирует поток выполнения.
const http = require('http');
const fs = require('fs');
const path = require('path');
const server = http.createServer((req, res) => {
// Преобразуем URL в путь к файлу
let filePath = '.' + req.url;
if (filePath === './') {
filePath = './index.html';
}
// Определяем MIME-тип по расширению файла
const extname = path.extname(filePath);
let contentType = 'text/html';
switch (extname) {
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
case '.json':
contentType = 'application/json';
break;
case '.png':
contentType = 'image/png';
break;
case '.jpg':
contentType = 'image/jpg';
break;
case '.gif':
contentType = 'image/gif';
break;
}
// Читаем файл
fs.readFile(filePath, (error, content) => {
if (error) {
if (error.code === 'ENOENT') {
// Файл не найден
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>404 Not Found</h1>');
} else {
// Другая ошибка (например, доступ запрещён)
res.writeHead(500, { 'Content-Type': 'text/html' });
res.end('<h1>500 Internal Server Error</h1>');
}
} else {
// Успешно: отправляем содержимое
res.writeHead(200, { 'Content-Type': contentType });
res.end(content);
}
});
});
server.listen(3000);
Почему важно правильно устанавливать Content-Type
Браузер использует Content-Type, чтобы понять, как обработать ответ:
text/html— отображает как страницуtext/css— применяет как стильtext/javascript— исполняет как скриптimage/png— показывает как изображениеapplication/json— ожидает JSON-структуру
Если Content-Type не указан или указан неверно — браузер может не загрузить CSS, не запустить JS или не показать картинку.
Обработка ошибок
ENOENT— файл не найден → 404 Not Found- Другие ошибки (например, нет прав на чтение) → 500 Internal Server Error
Важно: никогда не показывайте пользователю технические детали ошибок — только общие сообщения.
Почему не использовать fs.readFileSync()
readFileSync() — синхронный метод. Он блокирует весь сервер, пока файл не прочитан.
Пример:
const content = fs.readFileSync('./index.html'); // 💥 Блокирует поток!
res.end(content);
При одновременном запросе 100 пользователей — сервер на 100 мс будет «зависать» на каждом чтении. Это приведёт к полной остановке ответов.
В продакшене всегда используйте асинхронные методы:
fs.readFile(),fs.promises.readFile()
Синхронные методы (readFileSync,writeFileSync) — только для инициализации, скриптов, конфигов при запуске.