Что такое трехсотая серия ответов сервера?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое трехсотая серия ответов сервера (3xx коды)
3xx коды ответов — это класс HTTP статус-кодов, которые указывают на редирект (перенаправление). Сервер говорит браузеру: "Нужный ресурс находится в другом месте, перейди по новому адресу". Это один из наиболее важных механизмов веб-навигации.
Основные 3xx коды
300 - Multiple Choices
Сервер предлагает несколько вариантов для выбора:
// Редко используется, обычно сервер сам выбирает редирект
fetch('/api/resource')
.then(response => {
// Статус 300 означает, что есть несколько вариантов
if (response.status === 300) {
// Клиент должен выбрать один из вариантов
}
});
301 - Moved Permanently (постоянный редирект)
Ресурс безвозвратно переместился на новый URL:
// Браузер автоматически перенаправляет на новый URL
// Пример: старый домен -> новый домен
fetch('https://old-domain.com/page');
// Автоматически перейдет на https://new-domain.com/page
// Для SEO это важно - поисковики обновляют индекс
// На новый URL переходит весь "вес" старого URL
302 - Found (временный редирект)
Ресурс временно находится в другом месте:
// Пример: сохранение черновика перенаправляет на редактор
fetch('/api/posts', { method: 'POST', body: draftData })
.then(response => {
if (response.status === 302) {
// Ресурс временно находится в другом месте
// Браузер перейдет по Location заголовку
// В следующий раз может быть в другом месте
}
});
// Различие с 301:
// 301: ресурс переехал навсегда
// 302: ресурс временно в другом месте
303 - See Other
Используется после POST запроса - "посмотри результат в другом месте":
// POST запрос -> редирект на GET страницу результата
// Паттерн PRG (Post-Redirect-Get)
fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ username: 'user', password: 'pass' })
})
.then(response => {
if (response.status === 303) {
// Сервер говорит: перейди на GET страницу с результатом
// window.location = response.headers.get('Location');
}
});
304 - Not Modified (не кэшировать)
Ресурс не изменился - используй свой кэш:
// Браузер отправляет заголовки если-может-быть-изменено
fetch('/api/articles', {
headers: {
'If-Modified-Since': 'Wed, 21 Oct 2024 07:28:00 GMT',
'If-None-Match': '"33a64df551425fcc"' // ETag
}
})
.then(response => {
if (response.status === 304) {
// Не изменилось, используй кэш
// Экономим трафик и улучшаем производительность
const cachedData = localStorage.getItem('articles');
}
});
305 - Use Proxy
Нужно использовать прокси (редко):
// Очень редко используется
// Означает, что нужно переподключиться через прокси-сервер
307 - Temporary Redirect
Временный редирект, но сохраняет метод запроса:
// Отличие от 302:
// 302: браузер может изменить POST на GET при редиректе
// 307: браузер сохранит POST метод
fetch('/api/upload', {
method: 'POST',
body: formData
})
.then(response => {
if (response.status === 307) {
// Браузер повторит POST запрос на новый URL
// с теми же данными
}
});
308 - Permanent Redirect
Постоянный редирект, но сохраняет метод запроса:
// Отличие от 301:
// 301: браузер может изменить POST на GET при редиректе
// 308: браузер сохранит метод и данные
fetch('/api/old-endpoint', {
method: 'POST',
body: JSON.stringify({ data: 'test' })
})
.then(response => {
if (response.status === 308) {
// Браузер повторит POST запрос на /api/new-endpoint
// с теми же данными
}
});
Как браузер обрабатывает редиректы
// Автоматический редирект (браузер делает это сам)
fetch('/old-page')
.then(response => {
// Если было перенаправление, response содержит данные с нового URL
console.log(response.url); // Показывает финальный URL
return response.json();
});
// Если нужно отследить редирект (использовать mode: 'manual')
fetch('/old-page', { redirect: 'manual' })
.then(response => {
if (response.status === 301 || response.status === 302) {
// Вручную обрабатываем редирект
const newLocation = response.headers.get('Location');
// fetch(newLocation) для повторного запроса
}
});
Использование Location заголовка
// Сервер отправляет Location заголовок с новым URL
fetch('/old-endpoint')
.then(response => {
if (response.status >= 300 && response.status < 400) {
const newUrl = response.headers.get('Location');
console.log('Перенаправлено на:', newUrl);
// Браузер автоматически перейдет туда
}
});
Практические примеры
Редирект на https:
// Сервер настроен на редирект с http на https
fetch('http://example.com/page')
// Автоматически перенаправляется на https://example.com/page
.then(response => response.json());
Редирект после успешной авторизации:
// POST /login -> 303 See Other -> GET /dashboard
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify(credentials)
});
if (response.status === 303) {
window.location = response.headers.get('Location');
}
Версионирование API:
// GET /api/users -> 301 -> /api/v2/users
// Поисковики обновят индекс на новый URL
fetch('/api/users')
.then(response => {
// Получит данные с /api/v2/users
return response.json();
});
Таблица 3xx кодов
| Код | Название | Когда использовать |
|---|---|---|
| 300 | Multiple Choices | Несколько вариантов выбора (редко) |
| 301 | Moved Permanently | Ресурс безвозвратно переехал |
| 302 | Found | Временный редирект (может изменить метод) |
| 303 | See Other | После POST перейди на GET результат |
| 304 | Not Modified | Кэш актуален, не отправляем тело |
| 305 | Use Proxy | Использовать прокси (deprecated) |
| 307 | Temporary Redirect | Временный, сохрани метод запроса |
| 308 | Permanent Redirect | Постоянный, сохрани метод запроса |
Важные моменты для фронтенда
- Браузер автоматически следует 3xx редиректам - не нужно вручную перенаправлять
- fetch по умолчанию следует редиректам - используй
redirect: 'manual'если нужно контролировать - 301 и 308 - постоянные - браузер может кэшировать
- 302 и 307 - временные - браузер не кэширует
- Для логирования юзер остается на оригинальном URL - если не используется window.location
В целом, 3xx коды - это механизм перенаправления, который я использую для управления URL структурой, версионирования API и навигации пользователя в приложении.