Пошук уроків, статей та іншого контенту
Створите перший запит за допомогою fetch() і отримаєте відповідь від вебсервера.
Вебсторінка може не лише відображати заздалегідь підготовлений HTML, а й отримувати дані з вебсервера під час роботи. Наприклад:
список товарів з інтернет-магазину;
повідомлення користувача;
прогноз погоди;
дані профілю;
результати пошуку.
Для надсилання HTTP-запитів у браузері можна використовувати вбудовану функцію fetch().
fetch() не потребує встановлення додаткових бібліотек. Вона повертає Promise — об’єкт, який представляє результат асинхронної операції.
Синтаксис запиту виглядає так:
fetch("адреса")Наприклад:
fetch("https://jsonplaceholder.typicode.com/posts/1")Сервер поверне відповідь, але сам виклик fetch() ще не покаже її в консолі. Потрібно дочекатися завершення запиту та прочитати дані.
Для цього використаємо async і await:
async function getPost() {
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const post = await response.json();
console.log(post);
}
getPost();У результаті в консолі браузера буде об’єкт приблизно такого вигляду:
{
userId: 1,
id: 1,
title: "...",
body: "..."
}async function getPost() {
// код запиту
}Ключове слово async означає, що функція працює асинхронно та повертає Promise.
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");fetch() надсилає GET-запит за вказаною адресою.
Ключове слово await призупиняє виконання функції, доки сервер не поверне відповідь. При цьому браузер не зависає: користувач може продовжувати взаємодіяти зі сторінкою.
Змінна response містить об’єкт Response. Це ще не самі дані поста, а інформація про відповідь сервера.
Об’єкт Response має властивість ok. Вона дорівнює true, якщо сервер повернув успішний статус HTTP — від 200 до 299.
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}Наприклад, якщо ресурс не знайдено, сервер може повернути статус 404. У такому разі fetch() зазвичай не відхиляє Promise автоматично, тому статус потрібно перевіряти самостійно.
const post = await response.json();Метод json() читає тіло відповіді та перетворює JSON на JavaScript-об’єкт.
Це також асинхронна операція, тому перед нею використовується await.
Створіть файл index.html, відкрийте його в браузері та перегляньте результат на сторінці:
<!doctype html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>Запит за допомогою fetch()</title>
</head>
<body>
<h1>Пост із сервера</h1>
<p id="status">Завантаження...</p>
<article id="post"></article>
<script>
async function loadPost() {
const statusElement = document.querySelector("#status");
const postElement = document.querySelector("#post");
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}
const post = await response.json();
postElement.innerHTML = `
<h2>${post.title}</h2>
<p>${post.body}</p>
`;
statusElement.textContent = "Дані завантажено";
} catch (error) {
statusElement.textContent = "Не вдалося завантажити дані";
console.error("Помилка запиту:", error);
}
}
loadPost();
</script>
</body>
</html>Після завантаження сторінки програма:
знаходить елементи сторінки;
надсилає запит на сервер;
очікує відповідь;
перевіряє її статус;
перетворює JSON на об’єкт;
вставляє заголовок і текст поста в HTML;
показує повідомлення про результат.
Під час запиту можуть виникнути різні проблеми:
немає підключення до інтернету;
сервер недоступний;
адреса запиту неправильна;
сервер повернув помилку;
відповідь має неправильний формат.
Для обробки таких ситуацій використовують конструкцію try...catch:
async function loadData() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
if (!response.ok) {
throw new Error(`Сервер повернув статус ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Не вдалося отримати дані:", error);
}
}
loadData();Важливо: fetch() не вважає HTTP-статуси 404 або 500 помилкою мережі. У таких випадках Promise може успішно завершитися, але response.ok буде дорівнювати false. Саме тому статус відповіді потрібно перевіряти вручну.
then()Асинхронний код можна написати без async і await, використовуючи методи then() та catch():
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => {
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}
return response.json();
})
.then((post) => {
console.log(post.title);
})
.catch((error) => {
console.error("Помилка запиту:", error);
});Обидва варіанти працюють правильно. Для послідовних асинхронних операцій початківцям часто зручніше читати код із async і await.
Відповідь сервера може містити масив об’єктів. Наприклад, можна отримати кілька постів і показати їх на сторінці:
<!doctype html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>Список постів</title>
</head>
<body>
<h1>Список постів</h1>
<p id="message">Завантаження...</p>
<ul id="posts"></ul>
<script>
async function loadPosts() {
const messageElement = document.querySelector("#message");
const postsElement = document.querySelector("#posts");
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts?_limit=5"
);
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}
const posts = await response.json();
postsElement.innerHTML = posts
.map((post) => `<li>${post.title}</li>`)
.join("");
messageElement.textContent = "Пости завантажено";
} catch (error) {
messageElement.textContent = "Сталася помилка";
console.error(error);
}
}
loadPosts();
</script>
</body>
</html>Метод map() створює HTML-рядок для кожного поста, а join("") об’єднує всі рядки в один.
ResponseОб’єкт відповіді має корисні властивості та методи:
response.ok — чи успішний статус відповіді;
response.status — числовий HTTP-статус;
response.statusText — текстовий опис статусу;
response.json() — прочитати відповідь як JSON;
response.text() — прочитати відповідь як звичайний текст.
Наприклад:
const response = await fetch("https://example.com");
console.log(response.status);
console.log(response.ok);
const html = await response.text();
console.log(html);Тіло відповіді потрібно прочитати лише одним способом. Наприклад, після response.json() не можна повторно викликати response.text() для тієї самої відповіді.
Якщо другий аргумент не передано, fetch() виконує GET-запит:
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");GET-запити зазвичай використовують для отримання даних.
Не вставляйте отримані від користувачів або невідомих серверів дані через innerHTML без перевірки. Це може створити вразливість, якщо рядок містить HTML або JavaScript-код.
Для звичайного тексту безпечніше використовувати textContent:
titleElement.textContent = post.title;Якщо потрібно показати кілька елементів, можна створювати DOM-вузли через document.createElement() або переконатися, що дані походять із надійного джерела та не містять небезпечної розмітки.
awaitНеправильно:
const response = fetch("https://jsonplaceholder.typicode.com/posts/1");
console.log(response.status);У змінній response буде Promise, а не готова відповідь.
Правильно:
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
console.log(response.status);Цей код має виконуватися всередині async-функції.
json()Неправильно:
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
console.log(response);Це виведе об’єкт Response, а не дані поста.
Правильно:
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
const post = await response.json();
console.log(post);response.okНавіть якщо fetch() завершився без помилки JavaScript, сервер міг повернути статус 404 або 500.
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}Код без try...catch може залишити користувача без зрозумілого повідомлення, якщо сервер недоступний.
try {
// запит і обробка відповіді
} catch (error) {
// повідомлення про помилку
}Браузер контролює, з яких джерел сторінка може отримувати дані. Якщо сервер не дозволяє запити з вашого домену, браузер заблокує відповідь через політику CORS.
Це не можна надійно виправити лише JavaScript-кодом на клієнті. Потрібно, щоб сервер правильно налаштував заголовки доступу, або щоб запит виконувався через ваш сервер.
Створіть сторінку, яка:
має кнопку «Завантажити пост»;
після натискання надсилає запит за адресою: https://jsonplaceholder.typicode.com/posts/3;
показує заголовок і текст поста;
показує повідомлення про помилку, якщо запит не вдався.
Один із можливих варіантів:
<!doctype html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>Завантаження поста</title>
</head>
<body>
<button id="load-button">Завантажити пост</button>
<p id="message"></p>
<article id="post"></article>
<script>
const button = document.querySelector("#load-button");
const message = document.querySelector("#message");
const postElement = document.querySelector("#post");
button.addEventListener("click", async () => {
message.textContent = "Завантаження...";
postElement.textContent = "";
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/3"
);
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}
const post = await response.json();
const title = document.createElement("h2");
title.textContent = post.title;
const body = document.createElement("p");
body.textContent = post.body;
postElement.append(title, body);
message.textContent = "Пост завантажено";
} catch (error) {
message.textContent = "Не вдалося завантажити пост";
console.error(error);
}
});
</script>
</body>
</html>fetch() використовується для надсилання HTTP-запитів із браузера.
За замовчуванням fetch() виконує GET-запит.
Результатом fetch() є Promise.
await fetch(...) очікує отримання відповіді сервера.
response.json() перетворює JSON-відповідь на JavaScript-об’єкт.
response.ok потрібно перевіряти вручну.
try...catch допомагає обробляти помилки мережі та запитів.
Дані сервера можна показувати на сторінці через DOM-методи.