Кнопка завантаження показує успіх, хоча сервер повернув сторінку 404. У коді є try/catch, але очікуваного повідомлення про помилку немає. Це не означає, що JavaScript ігнорує винятки: fetch розрізняє отриману HTTP-відповідь і збій самого запиту. Обробка помилок fetch потребує явної перевірки статусу, а не тільки блоку catch навколо мережевого виклику.
Розберемо навчальну сторінку, яка читає маленький JSON із того самого локального сервера. Це не клієнтський кейс і не інтеграція з оплатою чи заявками. Потрібні сучасний браузер, редактор і локальний Python 3 для простого тестового сервера. Пакети та адміністративні права не потрібні. Використовуйте окрему папку лише з навчальними файлами: не запускайте сервер у каталозі із секретами, резервними копіями чи справжніми даними сайту.
Відповідь сервера ще не означає успішну операцію
Відкрийте вкладку Network у браузері й повторіть проблемну дію один раз. Подивіться на адресу запиту, HTTP-статус та тіло відповіді. Якщо сервер відповів 404 або 500, відповідь отримана, але запитаний ресурс не надано успішно. За документацією Fetch API, сам такий статус не відхиляє promise fetch. Тому перевіряти response.ok потрібно окремо, до використання даних.
Інший випадок — запит не завершився доступною відповіддю, наприклад через мережеву проблему. Тоді fetch може завершитися відхиленням promise. Порушений JSON є ще одним окремим етапом: відповідь могла мати успішний HTTP-статус, але її неможливо розібрати. Не називайте кожне потрапляння в catch «сервер недоступний». Для діагностики важливі етап, статус і безпечний технічний контекст, а не одна універсальна версія причини.
Почніть із малого відтворюваного прикладу. Створіть у тестовій папці index.html з розміткою нижче. Ідентифікатори load та status умовні, але повинні збігатися з селекторами в JavaScript. Атрибут defer дозволяє виконати підключений скрипт після розбору документа. Навчальні написи інтерфейсу залишені англійською, щоб однаковий код було зручно порівнювати між мовними версіями статті.
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Fetch test</title>
<button id="load" type="button">Load data</button>
<p id="status" role="status"></p>
<script src="app.js" defer></script>
</html>
Перевірте статус, дані та стан кнопки
Поруч створіть app.js і вставте код. Адреса ./data.json відноситься до каталогу сторінки; замініть її лише на погоджений тестовий ресурс. Приклад виконує GET і не надсилає форму. Він не додає авторизацію, не змінює CORS та не обходить захист сервера. Перед перенесенням у справжній застосунок збережіть попередній варіант компонента та перевіряйте зміни на тестовій копії.
const button = document.querySelector("#load");
const status = document.querySelector("#status");
button.addEventListener("click", async () => {
button.disabled = true;
status.textContent = "Loading...";
try {
const response = await fetch("./data.json");
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
if (typeof data?.message !== "string") {
throw new Error("Unexpected response shape");
}
status.textContent = data.message;
} catch (error) {
status.textContent = "Could not load data";
console.warn(error instanceof Error ? error.message : "Request failed");
} finally {
button.disabled = false;
}
});
Тут є три послідовні перевірки: доступний HTTP-результат, коректний JSON і рядкове поле message. response.ok охоплює успішні HTTP-статуси, але не підтверджує правильність бізнес-даних. Для навчальної схеми перевірки типу достатньо; для реального каталогу чи профілю потрібен власний контракт. Наприклад, успішна відповідь із полем error не повинна перетворюватися на повідомлення про завершену оплату лише через статус 200.
Текст показується через textContent, а не інтерпретується як HTML. Кнопка недоступна під час запиту та повертається в доступний стан у finally. Це зменшує випадкові повторні натискання в прикладі, але не є серверним захистом від дублікатів. Не переносіть таку гарантію на операції замовлення, листування або платежів. Автоматичних повторів тут немає: повторний запуск небезпечної операції потребує окремого проєктування.
Створіть третій файл data.json із наведеним вмістом. Поле й текст вигадані та призначені лише для перевірки. У терміналі перейдіть саме в навчальну папку та запустіть команду після прикладу JSON. Сервер прив’язаний до локальної адреси, не публічного інтерфейсу. Він тимчасово надає читання файлів цієї папки через HTTP; не використовуйте його як продуктивний сервер і не відкривайте доступ із мережі.
{"message":"Demo data loaded"}
python3 -m http.server 8099 --bind 127.0.0.1
Відкрийте http://127.0.0.1:8099/index.html і натисніть Load data. Очікуваний текст — Demo data loaded. Це очікування навчального сценарію, не результат вимірювання вашого сайту. Якщо порт зайнятий, виберіть інший вільний локальний порт та змініть адресу в браузері відповідно. Для завершення натисніть Ctrl+C у терміналі сервера. Параметри запуску описані в документації Python.
Доведіть, що обробляється саме потрібний збій
Спочатку тимчасово змініть у app.js адресу на ./missing-demo.json, переконавшись, що такого файла в папці немає. Перезавантажте сторінку й повторіть натискання. У Network очікується 404, у сторінці — повідомлення Could not load data, у консолі — HTTP 404. Саме наша перевірка response.ok створює виняток для цього випадку. Якщо локальне середовище повертає інший статус, дослідіть його, не підганяючи висновок під приклад.
Поверніть адресу та зробіть JSON навмисно некоректним, наприклад приберіть завершальну фігурну дужку. Перевірте повідомлення користувачу й консоль ще раз. HTTP-статус може бути 200, але розбір даних має завершитися помилкою. Потім відновіть JSON і замініть message числом: цього разу перевіряється форма даних. Після кожної вправи повертайте конкретну зміну, щоб наступний тест не маскувався попереднім збоєм.
Для справжнього сайту окремо перевірте повільну відповідь, скасування запиту та поведінку після переходу на іншу сторінку: цей мінімальний приклад їх не реалізує. Не виводьте відвідувачу повне тіло відповіді або внутрішній стек. Якщо помилку потрібно передати розробнику, підготуйте короткий багрепорт зі сценарієм і статусом без секретів. Висновок: перевіряйте кожен етап окремо. AriZone може допомогти узгодити повідомлення інтерфейсу з фактичним результатом API та перевірити виправлення на тестовому середовищі.
Залиште коментар