Пошук уроків, статей та іншого контенту
Передасте метод, заголовки, тіло та інші параметри через об’єкт налаштувань fetch().
fetch()Функція fetch() приймає URL ресурсу та необов’язковий другий аргумент — об’єкт налаштувань:
fetch(url, options);Наприклад:
fetch("https://example.com", {
method: "GET",
headers: {
Accept: "text/html"
}
});Об’єкт налаштувань дає змогу вказати:
HTTP-метод;
заголовки запиту;
тіло запиту;
режим роботи з CORS;
облікові дані, наприклад cookie;
спосіб кешування;
сигнал для скасування запиту.
Якщо другий аргумент не передати, fetch() виконає простий GET-запит.
methodВластивість method визначає HTTP-метод запиту:
fetch("/api/products", {
method: "GET"
});Найпоширеніші методи:
GET — отримати дані;
POST — створити нові дані;
PUT — повністю замінити дані;
PATCH — частково оновити дані;
DELETE — видалити дані.
Назву методу зазвичай записують великими літерами, хоча HTTP допускає й інший регістр.
Метод GET використовується за замовчуванням:
fetch("/api/products");Це те саме, що:
fetch("/api/products", {
method: "GET"
});headersЗаголовки передають додаткову інформацію про запит. Їх задають як об’єкт:
fetch("/api/products", {
headers: {
Accept: "application/json"
}
});Заголовок Accept повідомляє серверу, який формат відповіді очікує клієнт.
Для надсилання JSON зазвичай використовують заголовок Content-Type:
fetch("/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json"
}
});Назва "Content-Type" містить дефіс, тому її потрібно записати в лапках.
Можна передати кілька заголовків:
fetch("/api/products", {
headers: {
Accept: "application/json",
Authorization: "Bearer token-value",
"X-Client-Version": "1.0"
}
});Значення заголовка Authorization залежить від API та способу автентифікації. Не слід передавати в браузерному коді секретні ключі, які мають залишатися приватними.
bodyВластивість body містить дані, які надсилаються на сервер. Зазвичай тіло використовують із методами POST, PUT або PATCH.
Рядок можна передати безпосередньо:
fetch("/api/messages", {
method: "POST",
body: "Привіт, сервере!"
});Якщо потрібно передати JSON, об’єкт спочатку перетворюють на рядок за допомогою JSON.stringify():
const product = {
name: "Keyboard",
price: 1200
};
fetch("/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(product)
});body не повинен бути звичайним JavaScript-об’єктом:
// Неправильно: об’єкт не перетворено на JSON
fetch("/api/products", {
method: "POST",
body: product
});Правильний варіант:
fetch("/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(product)
});Нижче наведено приклад, який можна виконати в консолі браузера. Він надсилає новий запис на тестовий сервер і виводить відповідь:
async function createPost() {
const post = {
title: "Налаштування fetch()",
body: "Вивчаємо метод, заголовки та тіло запиту.",
userId: 1
};
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(post)
});
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}
const createdPost = await response.json();
console.log("Створений запис:", createdPost);
} catch (error) {
console.error("Не вдалося виконати запит:", error);
}
}
createPost();Розглянемо основні частини:
method: "POST" визначає тип запиту.
headers повідомляє, що тіло містить JSON і що відповідь також очікується у форматі JSON.
JSON.stringify(post) перетворює JavaScript-об’єкт на JSON-рядок.
await response.json() перетворює JSON-відповідь на JavaScript-об’єкт.
response.ok допомагає перевірити, чи має HTTP-відповідь успішний статус.
modemode визначає правила виконання кросдоменного запиту:
fetch("https://api.example.com/data", {
mode: "cors"
});Найпоширеніші значення:
"cors" — дозволяє кросдоменний запит, якщо сервер надав відповідні CORS-заголовки;
"same-origin" — дозволяє запити лише до того самого джерела;
"no-cors" — обмежений режим для окремих кросдоменних запитів.
Зазвичай браузерний код використовує стандартне значення mode. Якщо сервер не дозволяє запит із поточного домену, налаштування fetch() самостійно це не виправить. Сервер має правильно налаштувати CORS.
credentialscredentials визначає, чи потрібно додавати до запиту cookie та інші облікові дані:
fetch("/api/profile", {
credentials: "include"
});Можливі значення:
"omit" — не надсилати облікові дані;
"same-origin" — надсилати їх для запитів до того самого джерела;
"include" — надсилати їх також у кросдоменних запитах.
Значення за замовчуванням — "same-origin".
Для кросдоменних запитів із cookie сервер також повинен дозволити такі запити у своїх CORS-заголовках.
cacheВластивість cache визначає, як браузер взаємодіє з кешем:
fetch("/api/products", {
cache: "no-store"
});Поширені значення:
"default" — стандартна поведінка браузера;
"no-store" — не використовувати кеш для цього запиту;
"reload" — спробувати отримати свіжу відповідь;
"no-cache" — перевірити актуальність кешованої відповіді.
У більшості випадків достатньо стандартної поведінки. Спеціальні значення варто використовувати лише тоді, коли цього потребує логіка застосунку.
signal і скасування запитуІноді запит потрібно скасувати, наприклад якщо користувач перейшов на іншу сторінку або ввів новий пошуковий запит.
Для цього використовують AbortController:
const controller = new AbortController();
fetch("/api/products", {
signal: controller.signal
})
.then((response) => response.json())
.then((products) => {
console.log(products);
})
.catch((error) => {
if (error.name === "AbortError") {
console.log("Запит скасовано");
} else {
console.error("Помилка запиту:", error);
}
});
// Скасувати запит можна в будь-який момент
controller.abort();Властивість signal передає сигнал у fetch(), а виклик controller.abort() скасовує запит.
Об’єкт налаштувань описує лише запит. Відповідь потрібно опрацювати окремо:
async function loadProducts() {
const response = await fetch("/api/products", {
method: "GET",
headers: {
Accept: "application/json"
}
});
if (!response.ok) {
throw new Error(`Сервер повернув статус ${response.status}`);
}
const products = await response.json();
return products;
}Методи читання відповіді також повертають проміси:
response.json() — прочитати JSON;
response.text() — прочитати текст;
response.blob() — прочитати двійкові дані як Blob;
response.arrayBuffer() — прочитати дані як ArrayBuffer.
Тіло відповіді можна прочитати лише один раз. Наприклад, після response.json() не потрібно повторно викликати response.text() для тієї самої відповіді.
Для GET-запиту дані зазвичай передають не через body, а через параметри URL:
const searchParams = new URLSearchParams({
query: "javascript",
page: "2"
});
const response = await fetch(`/api/articles?${searchParams}`, {
method: "GET",
headers: {
Accept: "application/json"
}
});У результаті URL матиме такий вигляд:
/api/articles?query=javascript&page=2Для GET-запитів тіло зазвичай не використовують.
JSON.stringify()Неправильно:
const user = {
name: "Anna"
};
fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: user
});Правильно:
fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(user)
});Content-TypeЯкщо сервер очікує JSON, потрібно явно вказати формат тіла:
headers: {
"Content-Type": "application/json"
}Без цього сервер може не зрозуміти, як обробити отримані дані.
fetch() не відхиляє проміс автоматично для статусів 404 або 500. Тому потрібно перевіряти response.ok:
const response = await fetch("/api/data");
if (!response.ok) {
throw new Error(`HTTP-помилка: ${response.status}`);
}body у GETЗамість тіла для GET-запиту використовуйте параметри URL:
const params = new URLSearchParams({
category: "books"
});
fetch(`/api/products?${params}`);fetch() обійде CORSЯкщо сервер не дозволяє запити з поточного джерела, браузер заблокує такий запит. Це вирішується налаштуванням сервера або використанням серверного посередника, а не додаванням випадкових заголовків у клієнтському коді.
Створіть функцію updatePost(), яка:
надсилає PATCH-запит;
передає JSON із новим заголовком запису;
додає заголовки Accept і Content-Type;
перевіряє response.ok;
виводить оновлений об’єкт у консоль.
Приклад структури запиту:
async function updatePost() {
const updatedData = {
title: "Оновлений заголовок"
};
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "PATCH",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(updatedData)
});
if (!response.ok) {
throw new Error(`Помилка HTTP: ${response.status}`);
}
const updatedPost = await response.json();
console.log(updatedPost);
}
updatePost().catch((error) => {
console.error("Помилка:", error);
});Другий аргумент fetch() — це об’єкт налаштувань запиту.
method визначає HTTP-метод.
headers містить заголовки запиту.
body містить дані, які надсилаються на сервер.
JSON перед передаванням потрібно перетворити за допомогою JSON.stringify().
Для JSON-запиту потрібно вказати "Content-Type": "application/json".
Для GET-запитів параметри зазвичай додають до URL.
response.ok потрібно перевіряти вручну.
credentials, mode, cache і signal дають змогу керувати додатковими аспектами запиту.