Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
HTTP redirect (перенаправление) — это механизм, при котором сервер отправляет клиенту (обычно браузер) ответ с командой перейти на другой URL. Это делается с помощью HTTP статус-кодов в диапазоне 3xx (300-399) и заголовка Location.
Как это работает?
1. Клиент отправляет запрос на URL A
2. Сервер отвечает с кодом 3xx и указывает новый URL в Location
3. Браузер автоматически отправляет запрос на новый URL
4. Сервер отвечает с содержимым
Основные типы redirects
301 - Moved Permanently (постоянное перенаправление)
app.get('/old-url', (req, res) => {
res.redirect(301, '/new-url');
});
Используется, когда старый URL больше не существует. Google переносит SEO рейтинг.
302 - Found (временное перенаправление)
app.get('/temp-url', (req, res) => {
res.redirect(302, '/temporary-location');
});
Ресурс временно находится в другом месте. SEO не переносится.
303 - See Other (используется при POST запросах)
app.post('/process-form', (req, res) => {
// Обработка формы...
res.redirect(303, '/success-page');
});
Используется для паттерна PRG (Post-Redirect-Get).
304 - Not Modified (для кэширования)
app.get('/api/data', (req, res) => {
if (req.headers['if-none-match'] === etag) {
res.status(304).end();
} else {
res.json(data);
}
});
Данные в кэше еще актуальны.
307 - Temporary Redirect (сохраняет метод запроса)
app.post('/api/upload', (req, res) => {
res.redirect(307, '/api/v2/upload');
// POST запрос будет отправлен на новый URL
});
308 - Permanent Redirect (аналог 301 с сохранением метода)
app.post('/old-api', (req, res) => {
res.redirect(308, '/new-api');
// POST будет отправлен на новый URL
});
Практические примеры
const express = require('express');
const app = express();
// Простой redirect
app.get('/blog/:oldSlug', (req, res) => {
const newSlug = mapOldToNewSlug(req.params.oldSlug);
res.redirect(301, `/articles/${newSlug}`);
});
// Redirect с параметрами
app.get('/search', (req, res) => {
const query = req.query.q;
res.redirect(302, `/results?search=${encodeURIComponent(query)}`);
});
// Conditional redirect
app.get('/dashboard', (req, res) => {
if (!req.user) {
res.redirect(302, '/login');
} else {
res.json(req.user.dashboard);
}
});
// PRG паттерн (Post-Redirect-Get)
app.post('/api/data', (req, res) => {
saveData(req.body);
res.redirect(303, '/success');
});
Redirect vs Rewrite (важное различие!)
Redirect — браузер видит изменение URL
res.redirect(301, '/new-url');
// URL в адресной строке меняется
Rewrite — URL не меняется в браузере
app.get('/old-url', (req, res) => {
req.url = '/new-url';
next(); // Обработаем как /new-url
});
// URL в браузере остается /old-url
Когда использовать какой код?
| Код | Когда использовать |
|---|---|
| 301 | Старый URL навсегда исчез (SEO важна) |
| 302 | Временное перенаправление |
| 303 | После обработки формы (PRG паттерн) |
| 304 | Кэшированные данные не изменились |
| 307 | Временное, но сохраняй метод |
| 308 | Постоянное, но сохраняй метод |
Лучшие практики
// ✅ Хорошо: управляем кэшем при постоянном redirect
app.get('/old-api', (req, res) => {
res.status(301)
.set('Cache-Control', 'public, max-age=31536000')
.location('/new-api')
.end();
});
// ✅ Хорошо: явно управляем кэшем при временном redirect
app.get('/temp', (req, res) => {
res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
res.redirect(302, '/temp-location');
});
Недостатки redirects
- Дополнительный request — замедляет загрузку страницы
- SEO — теряется при неправильном использовании
- Redirect chains — A→B→C замедляет загрузку
- User Experience — пользователь может не заметить смену
Редиректы необходимы, но нужно выбирать правильный код для каждой ситуации.