HTTP-ошибка не равна сбою сети
fetch возвращает promise. Ответ сервера со статусом 404 или 500 сам по себе не заставляет этот promise отклониться: поэтому нужно проверить response.ok. Сбой соединения или отмена запроса обрабатываются как исключение.
Разбор JSON — отдельный шаг, который тоже может завершиться ошибкой. Сервер способен вернуть HTML вместо ожидаемых данных. Кроме успешного статуса, приложение должно понимать формат и структуру ответа.
Ограничьте время ожидания
Ниже функция для API, который вы контролируете. Путь /api/articles — пример: сначала создайте соответствующий endpoint или замените его адресом своего API.
async function loadArticles() {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 8000);
try {
const response = await fetch("/api/articles", {
signal: controller.signal,
headers: { Accept: "application/json" }
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} finally {
clearTimeout(timer);
}
}Не теряйте последнее действие
В поиске пользователь может быстро изменить запрос. Если старый ответ придёт после нового, он способен заменить правильные результаты. Отменяйте предыдущую загрузку или проверяйте идентификатор запроса перед обновлением интерфейса.
Вызывающая функция должна показать загрузку, перехватить ошибку и предложить повторить попытку. Ожидаемую отмену предыдущего поиска обычно не нужно представлять как ошибку пользователя.
Попробуйте сами
Проверьте свой интерфейс с отключённой сетью, медленным соединением и ответом 500. Убедитесь, что индикатор загрузки исчезает во всех трёх случаях.
Можно ли исправить CORS через mode: no-cors?
Это не даёт доступ к телу ответа: результат будет непрозрачным. Настройте разрешения на сервере или используйте собственный серверный прокси, если это соответствует архитектуре.
Документация и следующий шаг
Продолжите практику: TypeScript: уточняйте типы вместо any.