Пошук уроків, статей та іншого контенту
Розберете класи HTTP-статусів і навчитеся визначати успішні відповіді, помилки клієнта та проблеми сервера.
Коли клієнт надсилає HTTP-запит до сервера, сервер повертає відповідь. На початку відповіді є числовий статус-код, який повідомляє, чим завершилася операція.
Наприклад:
HTTP/1.1 200 OKУ цьому прикладі:
200 — статус-код;
OK — короткий текстовий опис;
відповідь успішна.
Статус-код складається з трьох цифр. Перша цифра визначає загальний клас результату.
1xx — інформаційні відповідіЦі коди повідомляють про проміжний стан обробки запиту.
Найчастіше розробники майже не працюють із ними безпосередньо.
Приклад:
100 Continue — сервер отримав початок запиту й очікує його продовження.
2xx — успішне виконанняСервер отримав і успішно обробив запит.
Поширені коди:
200 OK — запит успішний;
201 Created — ресурс створено;
202 Accepted — запит прийнято для подальшої обробки;
204 No Content — запит успішний, але тіло відповіді відсутнє.
Приклади:
GET /users/1 може повернути 200;
POST /users може повернути 201;
DELETE /users/1 часто повертає 204.
3xx — перенаправленняКлієнту потрібно виконати додаткову дію, наприклад перейти за іншою адресою або використати кешовану версію ресурсу.
Поширені коди:
301 Moved Permanently — ресурс назавжди переміщено;
302 Found — тимчасове перенаправлення;
304 Not Modified — ресурс не змінився, можна використати кеш.
Браузер зазвичай обробляє перенаправлення автоматично.
4xx — помилки клієнтаЗапит містить проблему з боку клієнта: неправильні дані, відсутні права або неіснуюча адреса.
Поширені коди:
400 Bad Request — неправильний формат запиту;
401 Unauthorized — потрібна автентифікація;
403 Forbidden — доступ заборонено;
404 Not Found — ресурс не знайдено;
405 Method Not Allowed — HTTP-метод не підтримується;
409 Conflict — конфлікт із поточним станом ресурсу;
422 Unprocessable Entity — дані зрозумілі, але не проходять перевірку;
429 Too Many Requests — забагато запитів за короткий час.
Наприклад, якщо користувач намагається відкрити /users/999, а такого користувача немає, сервер може повернути 404.
5xx — помилки сервераСервер не зміг коректно обробити правильний або прийнятний запит.
Поширені коди:
500 Internal Server Error — внутрішня помилка сервера;
502 Bad Gateway — проміжний сервер отримав неправильну відповідь;
503 Service Unavailable — сервіс тимчасово недоступний;
504 Gateway Timeout — сервер не дочекався відповіді від іншого сервера.
Такі помилки зазвичай не означають, що користувач неправильно заповнив форму. Клієнт може показати повідомлення про тимчасову проблему або повторити запит пізніше.
Метод fetch() повертає об'єкт Response. У ньому є властивості для перевірки результату:
response.status — числовий статус-код;
response.statusText — текстовий опис статусу;
response.ok — true, якщо статус належить до діапазону 200–299;
response.headers — заголовки відповіді.
fetch("https://jsonplaceholder.typicode.com/users/1")
.then((response) => {
console.log("Статус:", response.status);
console.log("Опис:", response.statusText);
console.log("Успішна відповідь:", response.ok);
if (!response.ok) {
throw new Error(`HTTP-помилка: ${response.status}`);
}
return response.json();
})
.then((user) => {
console.log("Користувач:", user);
})
.catch((error) => {
console.error("Не вдалося отримати дані:", error.message);
});Цей код можна виконати в консолі браузера. Він надсилає запит, перевіряє статус і читає JSON-відповідь.
fetch()fetch() не вважає статуси 4xx і 5xx помилками JavaScript автоматично.
Наприклад, запит із відповіддю 404 зазвичай успішно завершує проміс:
fetch("/missing-page")
.then((response) => {
console.log(response.status); // Наприклад, 404
})
.catch((error) => {
// Цей блок не обов'язково виконається через статус 404
console.error(error);
});catch() спрацьовує переважно тоді, коли запит не вдалося виконати взагалі:
немає мережевого з'єднання;
виникла помилка DNS;
запит заблокований політикою браузера;
URL має некоректний формат;
запит було скасовано.
Тому статус потрібно перевіряти вручну через response.ok або response.status.
Для різних класів помилок можна показувати користувачу різні повідомлення:
async function loadUser(id) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${id}`
);
if (response.ok) {
return response.json();
}
if (response.status === 404) {
throw new Error("Користувача не знайдено");
}
if (response.status === 401) {
throw new Error("Потрібно увійти в систему");
}
if (response.status >= 500) {
throw new Error("Сервер тимчасово недоступний");
}
throw new Error(`Помилка запиту: ${response.status}`);
}
loadUser(1)
.then((user) => {
console.log("Ім'я користувача:", user.name);
})
.catch((error) => {
console.error(error.message);
});Порівняння response.status >= 500 дає змогу обробити всі основні серверні помилки одним правилом.
Сервер може повернути корисну інформацію разом із помилкою. Наприклад:
{
"message": "Email уже використовується"
}Її можна прочитати з JSON і показати користувачу.
async function createUser(userData) {
const response = await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(userData)
});
let body = null;
try {
body = await response.json();
} catch {
// Відповідь може не містити JSON
}
if (!response.ok) {
const message =
body?.message || `Запит завершився зі статусом ${response.status}`;
throw new Error(message);
}
return body;
}
createUser({
name: "Олена",
email: "olena@example.com"
})
.then((user) => {
console.log("Створено користувача:", user);
})
.catch((error) => {
console.error("Не вдалося створити користувача:", error.message);
});У цьому прикладі:
надсилається POST-запит;
тіло запиту перетворюється на JSON;
відповідь намагається прочитатися як JSON;
перевіряється response.ok;
повідомлення сервера використовується для пояснення помилки.
204Не кожна успішна відповідь містить JSON. Наприклад, після видалення ресурсу сервер може повернути 204 No Content.
У такому випадку не можна безумовно викликати response.json(), бо тіло порожнє.
async function deleteUser(id) {
const response = await fetch(`/api/users/${id}`, {
method: "DELETE"
});
if (!response.ok) {
throw new Error(`Не вдалося видалити користувача: ${response.status}`);
}
if (response.status === 204) {
return null;
}
return response.json();
}Статус відповіді варто перетворити на зрозумілий стан інтерфейсу:
200–299 — показати отримані дані;
400 або 422 — показати помилки введених даних;
401 — попросити користувача увійти;
403 — повідомити про відсутність дозволу;
404 — повідомити, що ресурс не знайдено;
429 — попросити повторити спробу пізніше;
500–599 — показати повідомлення про проблему сервера.
Клієнт не повинен показувати користувачу незрозуміле повідомлення на кшталт Error 500. Краще пояснити ситуацію простою мовою.
Наприклад:
function getErrorMessage(status) {
switch (status) {
case 400:
return "Перевірте введені дані";
case 401:
return "Увійдіть у свій обліковий запис";
case 403:
return "У вас немає доступу до цієї дії";
case 404:
return "Ресурс не знайдено";
case 429:
return "Забагато запитів. Спробуйте пізніше";
default:
if (status >= 500) {
return "Сервер тимчасово недоступний";
}
return "Сталася невідома помилка";
}
}
console.log(getErrorMessage(404));
console.log(getErrorMessage(503));Для більшості запитів можна використовувати такий алгоритм:
Виконати fetch().
Перевірити response.ok.
Якщо відповідь успішна — прочитати тіло.
Якщо статус 4xx — показати або обробити помилку клієнта.
Якщо статус 5xx — повідомити про проблему сервера.
Перехопити мережеві помилки через try...catch.
async function loadProducts() {
try {
const response = await fetch("/api/products");
if (!response.ok) {
if (response.status === 404) {
throw new Error("Список товарів не знайдено");
}
if (response.status >= 500) {
throw new Error("Сервіс товарів тимчасово недоступний");
}
throw new Error(`Помилка HTTP: ${response.status}`);
}
const products = await response.json();
console.log("Товари:", products);
} catch (error) {
console.error("Помилка завантаження:", error.message);
}
}
loadProducts();catch()fetch("/api/users")
.then((response) => response.json())
.catch((error) => {
console.error(error);
});Такий код може спробувати обробити відповідь 404 або 500 як звичайні дані.
Правильніше спочатку перевірити response.ok.
2xx однаковимСтатуси 200, 201 і 204 означають успіх, але мають різний зміст:
200 зазвичай містить дані;
201 означає створення ресурсу;
204 не містить тіла відповіді.
response.json() двічіТіло відповіді можна прочитати лише один раз:
const data = await response.json();Після цього повторний виклик response.json() призведе до помилки. Якщо дані потрібні в кількох місцях, збережіть їх у змінну.
Для 204 не слід викликати response.json() без перевірки. Спочатку потрібно визначити, чи містить відповідь тіло.
Статус 403 корисний розробнику, але користувачу зрозуміліше повідомлення «У вас немає доступу до цієї дії».
HTTP-статус-код показує результат обробки запиту.
Коди 1xx є інформаційними, 2xx означають успіх, 3xx — перенаправлення, 4xx — помилки клієнта, 5xx — помилки сервера.
У fetch() властивість response.ok дорівнює true лише для статусів 200–299.
Статуси 4xx і 5xx не спричиняють автоматичного переходу в catch().
Мережеві помилки та HTTP-помилки потрібно обробляти окремо.
Статус 204 означає успішну відповідь без тіла.
Обробляйте статуси так, щоб користувач отримував зрозуміле повідомлення, а не лише номер помилки.