1. Введение
Статические файлы — это любые файлы, которые не генерируются динамически сервером, а лежат на диске в неизменном виде. Это могут быть:
- HTML-файлы (если вы не используете шаблонизаторы)
- CSS-стили
- JavaScript-файлы для фронтенда
- Картинки, иконки, шрифты, PDF и т.д.
Когда браузер загружает вашу страницу, он обычно делает дополнительные запросы на сервер за этими файлами. Если сервер не умеет их отдавать — сайт будет выглядеть как сломанный пазл: без картинок, без стилей, без интерактива.
Зачем вообще отдавать статику через Express?
- Чтобы не писать велосипед: Express умеет быстро и безопасно отдавать файлы, заботится о заголовках и ошибках.
- Чтобы не использовать отдельный сервер только для статики (например, nginx или Apache) на этапе разработки.
- Чтобы легко раздавать файлы прямо из папки вашего проекта.
Встроенный middleware express.static: как это работает
Express поставляется с готовым middleware express.static, который позволяет одной строчкой кода настроить отдачу всех файлов из определённой папки.
Синтаксис
const express = require('express');
const app = express();
// Все файлы из папки 'public' будут доступны по адресу http://localhost:3000/имя_файла
app.use(express.static('public'));
- 'public' — это относительный путь к папке с вашими статическими файлами (обычно в корне проекта).
- Теперь, если в папке public лежит файл style.css, его можно получить по адресу http://localhost:3000/style.css.
Как это работает?
Когда Express получает HTTP-запрос, он сначала проверяет, не подходит ли путь под ваш express.static. Если файл найден — Express возвращает его содержимое и завершает обработку запроса (другие middleware уже не вызываются).
2. Практика: подключаем статику к нашему приложению
Давайте продолжим развитие нашего учебного приложения. Допустим, у нас есть папка public, в которой лежит файл index.html, а также стили и картинки.
Структура проекта:
/my-app
/public
index.html
style.css
logo.png
app.js
Код app.js:
const express = require('express');
const app = express();
const PORT = 3000;
// Подключаем middleware для статики
app.use(express.static('public'));
app.listen(PORT, () => {
console.log(`Сервер запущен на http://localhost:${PORT}`);
});
Теперь если вы откроете в браузере http://localhost:3000/index.html, увидите ваш HTML-файл. А если внутри него есть <link rel="stylesheet" href="style.css">, Express автоматически отдаст и файл стилей!
Пример index.html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Мой Express-сайт</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Добро пожаловать!</h1>
<img src="logo.png" alt="Логотип">
</body>
</html>
Пример style.css
body {
background: #f0f0f0;
font-family: sans-serif;
}
h1 {
color: #3366cc;
}
Всё, что лежит в public, становится доступно по прямым ссылкам!
4. Полезные нюансы
Как Express ищет файлы: путь, вложенность, безопасность
Express ищет файл по тому же пути, что и в URL. Например:
- /style.css → public/style.css
- /images/photo.jpg → public/images/photo.jpg
Вложенные папки поддерживаются! Просто создайте папки внутри public, и файлы будут доступны так же.
Безопасность: Express не отдаёт файлы вне указанной папки (никаких "выходов" наверх по файловой системе). Если файл не найден — Express просто передаёт запрос дальше по цепочке middleware или возвращает 404.
Настройки express.static: кастомизация поведения
express.static принимает не только путь, но и объект опций. Вот некоторые полезные параметры:
- index: имя файла по умолчанию (например, если пользователь зашёл на /, будет отдан index.html)
- extensions: массив расширений, которые Express будет пробовать, если расширение не указано.
- maxAge: время кэширования файлов в браузере (например, maxAge: '1d' — кэшировать сутки).
- fallthrough: если false, при ошибке Express сразу вернёт ошибку, а не передаст управление дальше.
Пример:
app.use(express.static('public', {
index: 'index.html',
maxAge: '2h'
}));
Это заставит браузер кэшировать ваши стили и картинки на 2 часа.
Использование нескольких папок для статики
Иногда хочется раздавать статику из разных мест (например, картинки в одной папке, скрипты — в другой). Можно подключить несколько экземпляров express.static с разными путями:
app.use(express.static('public'));
app.use('/images', express.static('uploads/images'));
Теперь по адресу /images/cat.jpg будет искаться файл uploads/images/cat.jpg.
Префикс для статики: отдаём файлы по другому URL
Иногда не хочется, чтобы вся ваша статика была доступна с корня сайта. Например, вы хотите, чтобы все картинки были доступны по /static/. Это легко сделать:
app.use('/static', express.static('public'));
Теперь файл public/logo.png будет доступен по адресу /static/logo.png.
Как express.static вписывается в цепочку middleware
Порядок подключения middleware очень важен! Если вы сначала подключите обработчики маршрутов, а потом static — Express не сможет отдавать файлы, потому что до них просто не дойдёт.
Правильный порядок:
app.use(express.static('public')); // Сначала статика
// Потом — ваши маршруты
app.get('/api/data', (req, res) => {
res.json({ hello: 'world' });
});
Если пользователь запрашивает файл, Express отдаёт его и не вызывает ваши маршруты. Если файл не найден — запрос идёт дальше, и тогда уже срабатывают ваши обработчики.
5. Типичные ошибки при работе с express.static
Ошибка №1: не тот путь к папке
Очень часто новички пишут:
app.use(express.static('./public'));
Это работает, если ваш сервер всегда запускается из корня проекта. Но если запускать из другой папки — путь ломается. Лучше использовать абсолютный путь:
const path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
Ошибка №2: неправильный порядок middleware
Если вы сначала объявили маршруты, а потом static — файлы не будут отдаваться. Всегда подключайте express.static раньше всех обработчиков.
Ошибка №3: забыли положить файлы в папку
Иногда вы указываете папку, а нужных файлов там нет. Express просто вернёт 404, а вы долго ищете "баг" в коде.
Ошибка №4: используете относительные пути в HTML
Если вы настроили префикс (/static), то в <img src="logo.png"> ничего не загрузится. Нужно писать <img src="/static/logo.png">.
Ошибка №5: кэширование мешает обновлению файлов
Если вы включили кэширование (например, maxAge: '1d'), то браузер может продолжать показывать старые версии файлов, даже если вы их изменили. На этапе разработки лучше не включать кэширование или ставить maxAge: 0.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ