Где Next.js тратит ресурсы
| Адрес | Нагрузка | Правило |
|---|---|---|
| Страницы с динамическим рендерингом | Рендер на каждый запрос, обращения к базе и внешним API | Лимиты и проверка браузера для подозрительных источников |
| /_next/image | Масштабирование и сжатие картинок на лету | Лимит на уникальные сочетания url, w и q; кэш результатов |
| /api/* и Route Handlers | Код приложения | Лимиты по сессии, токену и методу |
| POST с заголовком Next-Action | Server Actions | Лимиты по пути страницы и заголовку |
| /_next/data/* (Pages Router) | JSON для переходов между страницами | Те же правила, что для самих страниц |
| /_next/static/* | Статика с хешем в имени файла | Кэшировать надолго, не ограничивать агрессивно |
Оптимизатор изображений принимает параметры url, w и q. Ограничьте в next.config список разрешённых источников (images.remotePatterns) и размеров (deviceSizes, imageSizes): тогда запросы с произвольными значениями получают ошибку, а не запускают обработку.
ISR и revalidate
Страницы с revalidate отдаются из кэша и перегенерируются в фоне, поэтому они устойчивее к флуду. Но маршрут, который вызывает revalidatePath или revalidateTag по запросу CMS, нужно защитить секретом и лимитом: иначе его можно дёргать, чтобы постоянно сбрасывать кэш.
Middleware
Файл middleware.ts (в Next.js 16 — proxy.ts) выполняется на каждый подходящий запрос. Ограничьте его через config.matcher, исключив /_next/static, /_next/image и файлы статики, — иначе даже запросы картинок проходят через лишний код.
Реальный IP в Node.js
У next start нет настройки доверенных прокси: приложение видит X-Forwarded-For в том виде, в каком его передал предыдущий узел. Поэтому адрес нужно восстановить на nginx модулем real_ip по адресам фильтра и перезаписать заголовки, а не дописывать к ним. В Express и Fastify для этого есть настройка trust proxy со списком доверенных адресов.
# nginx перед Next.js; $remote_addr уже восстановлен модулем real_ip
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}// Express: доверять только локальному nginx и узлам фильтрации (адреса условные)
app.set('trust proxy', ['loopback', '203.0.113.0/24']);Что исключить из проверки браузера
- Вебхуки в /api/webhooks/* и подобных маршрутах — их подлинность проверяет подпись отправителя.
- Маршрут on-demand revalidation, который вызывает CMS.
- Запросы мобильного приложения к API: для них — лимиты и подпись запросов.
- Задачи по расписанию, запускаемые HTTP-запросом, — по адресу источника и секрету.
Типичные ошибки
- Жёсткий лимит частоты на /_next/static: при первой загрузке страница запрашивает десятки файлов, и настоящие посетители получают 429.
- Страница стала динамической из-за чтения cookies или headers там, где её можно было отдать из кэша.
- Порт 3000 открыт наружу — атаку можно направить на приложение в обход nginx и фильтра. Закройте его и скройте IP сервера.
Вопросы и ответы
Подходит ли это для приложений на управляемых платформах вроде Vercel?
Рекомендации на странице рассчитаны на самостоятельный хостинг. У управляемых платформ собственный пограничный слой, и схему подключения внешнего фильтра перед ними стоит обсуждать отдельно — опишите её в заявке на ранний доступ.
Работают ли WebSocket и потоковый рендеринг?
Фильтр уровня L7 рассчитан на HTTP, HTTPS и WebSocket. Для потоковых ответов (streaming SSR, Server-Sent Events) важно, чтобы промежуточные узлы не буферизовали ответ целиком: в nginx это proxy_buffering off или заголовок X-Accel-Buffering: no на нужных маршрутах.
Читайте также
- ВозможностиКэширование и ускорение сайтаОтдача статики и страниц с узлов фильтрации
- ВозможностиЗащита API от DDoS, ботов и злоупотребленийЛимиты по ключам, схема запросов, защита мобильных приложений
- АтакиHTTP-флуд: что это и как защититьсяМассовые запросы к страницам, которые перегружают сервер
- ВозможностиСокрытие IP-адреса сервераСкрываем настоящий адрес сервера и закрываем обходные пути