← Назад к вопросам
Как понять как завершился REST-запрос?
1.8 Middle🔥 191 комментариев
#Браузер и сетевые технологии
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как понять как завершился REST-запрос?
HTTP статус-коды
REST-запрос завершается с определённым статус-кодом, который указывает на результат:
2xx — Success (успешно)
- 200 OK — запрос успешен, ответ содержит данные
- 201 Created — ресурс создан (обычно для POST)
- 204 No Content — успех, но нет данных в ответе (обычно для DELETE)
3xx — Redirection (перенаправление)
- 301 Moved Permanently — ресурс переехал навсегда
- 307 Temporary Redirect — временное перенаправление
4xx — Client Error (ошибка клиента)
- 400 Bad Request — неверный формат запроса
- 401 Unauthorized — не авторизован
- 403 Forbidden — доступ запрещён
- 404 Not Found — ресурс не найден
- 422 Unprocessable Entity — логическая ошибка (валидация не пройдена)
- 429 Too Many Requests — слишком много запросов (rate limit)
5xx — Server Error (ошибка сервера)
- 500 Internal Server Error — внутренняя ошибка
- 503 Service Unavailable — сервис недоступен
Методы проверки в коде
// === FETCH API ===
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`);
// Способ 1: Проверить status напрямую
if (response.status === 200) {
const data = await response.json();
return { success: true, data };
}
// Способ 2: Использовать response.ok (true для 200-299)
if (response.ok) {
const data = await response.json();
return { success: true, data };
} else {
const error = await response.json();
return { success: false, error };
}
}
// === AXIOS ===
import axios from 'axios';
async function fetchUserWithAxios(id) {
try {
// Axios автоматически выбрасывает ошибку для статусов вне 2xx
const { data, status } = await axios.get(`/api/users/${id}`);
console.log(`Запрос успешен, код ${status}`);
return data;
} catch (error) {
// Ошибка сети или статус >= 400
if (error.response) {
// Сервер вернул ошибку (4xx/5xx)
console.error(`Ошибка ${error.response.status}: ${error.response.data.message}`);
} else if (error.request) {
// Запрос отправлен, но ответа нет (сеть)
console.error('Нет ответа от сервера');
} else {
// Ошибка при создании запроса
console.error('Ошибка запроса:', error.message);
}
throw error;
}
}
// === СОВРЕМЕННЫЙ ПОДХОД: Типизированный wrapper ===
type ApiResponse<T> =
| { ok: true; data: T; status: number }
| { ok: false; error: string; status: number };
async function apiRequest<T>(
url: string,
options?: RequestInit
): Promise<ApiResponse<T>> {
try {
const response = await fetch(url, options);
const data = await response.json();
if (response.ok) {
return { ok: true, data, status: response.status };
} else {
return { ok: false, error: data.message || 'Unknown error', status: response.status };
}
} catch (error) {
return { ok: false, error: 'Network error', status: 0 };
}
}
// Использование:
const result = await apiRequest<User>('/api/users/123');
if (result.ok) {
console.log('Пользователь:', result.data);
} else {
console.error('Ошибка:', result.error);
}
Проверка в React компоненте
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUser = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch(`/api/users/${userId}`);
// Проверяем статус
if (!response.ok) {
// Обработка конкретных ошибок
switch (response.status) {
case 404:
setError('Пользователь не найден');
break;
case 401:
setError('Необходима авторизация');
break;
case 500:
setError('Ошибка сервера, попробуйте позже');
break;
default:
setError(`Ошибка ${response.status}`);
}
return;
}
const data = await response.json();
setUser(data);
} catch (err) {
// Сетевая ошибка или ошибка парсинга JSON
setError('Ошибка сети');
console.error(err);
} finally {
setLoading(false);
}
};
fetchUser();
}, [userId]);
if (loading) return <p>Загрузка...</p>;
if (error) return <p style={{ color: 'red' }}>{error}</p>;
if (!user) return <p>Нет данных</p>;
return <div>{user.name}</div>;
}
Headers ответа и их значение
async function analyzeResponse() {
const response = await fetch('/api/data');
// Полезные headers:
console.log(response.headers.get('content-type')); // 'application/json'
console.log(response.headers.get('content-length')); // размер в байтах
console.log(response.headers.get('cache-control')); // кэширование
console.log(response.headers.get('x-ratelimit-remaining')); // осталось запросов
console.log(response.headers.get('retry-after')); // когда повторить (если 429)
// Проверка content-type перед парсингом
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
const json = await response.json();
return json;
} else {
const text = await response.text();
return text;
}
}
Debugging в DevTools
// === Вкладка Network в DevTools ===
// 1. Откройте F12 -> Network
// 2. Отправьте запрос
// 3. Кликните на запрос в списке
// 4. Справа увидите:
// - Status (200, 404, etc.)
// - Headers (request & response)
// - Response body
// - Timing (как долго загружалось)
// === Фильтрация запросов ===
// Введите в фильтр:
// status-code:404 // только ошибки
// -status-code:200 // всё кроме успехов
// /api // только API запросы
// === Сохранение логов ===
// Кликните gear icon -> Preserve log (сохранять при навигации)