fetch("https://jsonplaceholder.typicode.com/users")
.then(response => {
// Response handling
})
.then(data => {
// Data handling
})
.catch(error => {
// Error handling
});
===== Коди відповідей сервера HTTP/s =====
[[https://www.webfx.com/web-development/glossary/http-status-codes/|Довідник HTTP-кодів]]
* 1XX — мають інформаційне призначення
* 2XX — коди успішного проведення операції
* 3XX — описують усе, що пов'язано з перенаправленням (redirect)
* 4XX — вказують на помилки з боку клієнта
* 5XX — вказують на помилки з боку сервера
* 200 (OK) — стандартна відповідь для успішних HTTP-запитів.
* 201 (Created) — стандартна відповідь для HTTP-запиту, який привів до успішного створення ресурсу.
* 400 (Bad Request) — запит не може бути оброблений через неправильний синтаксис запиту або іншу помилку клієнта.
* 401 (Unauthorized) — для доступу до ресурсу вимагається авторизація.
* 403 (Forbidden) — у клієнта немає дозволу на доступ до цього ресурсу.
* 404 (Not Found) — у цей час ресурс не знайдений. Можливо, він був видалений або ще не існує.
* 500 (Internal Server Error) — загальна відповідь на непередбачений збій сервера, якщо відсутня конкретніша інформація.
===== fetch (перевірка відповіді) =====
Значення промісу, який повертає метод fetch() — це об'єкт зі службовою інформацією про стан відповіді сервера. Цей об’єкт є екземпляром класу Response, який включає різні методи та властивості. Залежно від типу отримуваного контенту, використовуються різні методи для перетворення тіла відповіді у дані.
* **json()** — парсить дані у JSON-форматі.
* **text()** — парсить дані у простому текстовому форматі, наприклад .csv (табличні дані).
* **blob()** — парсить дані, що описують файл, наприклад, зображення, аудіо або відео.
У прикладі нижче в першому методі then() виконується перевірка статусу відповіді й перетворення даних у правильний формат (парсинг) у разі успішного результату або явне створення помилки, щоб обробити невдалий HTTP-запит у методі catch().
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then(data => {
// Data handling
console.log(data);
})
.catch(error => {
// Error handling
console.log(error);
});
===== HTTP-методи (CRUD) =====
* **POST** — створити новий ресурс (**C**reate)
* **GET** — отримати набір ресурсів або один ресурс (**R**ead)
* **PUT** — оновити існуючий або створити новий ресурс (**U**pdate)
* **PATCH** — оновити існуючий ресурс (Update)
* **DELETE** — видалити ресурс(**D**elete)
= CRUD
const options = {
method: "GET"
};
fetch("", options)
.then(response => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then(data => {
// Data handling
})
.catch(error => {
// Error handling
});
**Для GET-запиту вказувати його в опціях fetch не потрібно, це метод запиту за замовчуванням.**
===== HTTP-заголовки =====
Заголовки містять службову інформацію, що стосується запиту або відповіді.
Наприклад:
* Текстовий файл, який містить HTML, буде описаний типом text/html.
* Якщо текстовий файл містить CSS, він буде описаний як text/css.
* Дані у форматі JSON будуть описані як application/json.
Наприклад, якщо ми хочемо явно вказати, що у відповіді від бекенда ми очікуємо тільки JSON, то для цього додаємо заголовок Accept зі значенням application/json.
fetch("https://jsonplaceholder.typicode.com/users", {
headers: {
Accept: "application/json",
},
}).then(response => {
// ...
});
===== Кросдоменні запити =====
За замовчуванням HTTP-запит можна робити тільки в рамках поточного сайту. При спробі запиту на інший домен, порт або протокол (тобто при спробі виконати кросдоменний запит), браузер видає помилку. Це зроблено з міркувань безпеки, і права доступу налаштовуються на бекенді. Якщо бекенд не підтримує кросдоменні запити, фронтенд-розробник нічого не зможе з цим зробити у своєму коді.
На кожному запиті браузер сам додає HTTP-заголовок Origin, де вказує адресу вебсторінки, яка хоче зробити HTTP-запит. Наприклад, якщо ми робимо fetch-запит із вебсторінки https://my-site.com/about на https://my-api.com/users, то заголовки будуть наступними:
GET /users
Host: my-api.com
Origin:
===== AJAX (Asynchronous JavaScript and XML) =====
Метод отримання або відправлення даних з подальшим оновленням інтерфейсу за цими даними, без потреби перезавантаження сторінки. Завдяки цьому зменшується час відгуку і вебсторінка стає інтерактивнішою.
Незважаючи на те, що в назві технології присутній XML, у сучасному інтернеті його замінив JSON, а назву залишили як данину пам'яті. AJAX трактується як будь-яке спілкування з сервером без перезавантаження сторінки.
const fetchUsersBtn = document.querySelector(".btn");
const userList = document.querySelector(".user-list");
fetchUsersBtn.addEventListener("click", () => {
fetch("")
.then((response) => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then((users) => {
const markup = users.map((user) => {
return `
Name: ${user.name}
Email: ${user.email}
Company: ${user.company.name}
`;
})
.join("");
userList.insertAdjacentHTML("beforeend", markup);
})
.catch((error) => console.log(error));
});
====== GET (Запит) ======
===== Параметри рядка запиту =====
Символ ? вказує на початок параметрів запиту. Кожен параметр — це пара ім'я=значення.
fetch("https://jsonplaceholder.typicode.com/users?_limit=7&_sort=name")
==== Клас URLSearchParams ====
Параметрів може бути багато, і незручно складати з них один довгий рядок як для читабельності, так і для його подальшого редагування.
Під час складання рядків параметрів, створюється екземпляр класу URLSearchParams та ініціалізується об'єктом. Результатом буде спеціальний об'єкт (ітератор) з методами, який у рядковому перетворенні повертає результат виклику методу toString() — своє рядкове відображення.
**Приклад 1**
const searchParams = new URLSearchParams({
_limit: 5,
_sort: "name",
});
console.log(searchParams.toString()); // "_limit=5&_sort=name"
const url = `https://jsonplaceholder.typicode.com/users?${searchParams}`;
console.log(url); // ""
У разі інтерполяції значення в шаблонних рядках відбувається його неявне перетворення в рядок, тому не потрібно викликати метод toString() під час складання URL. Не забувай вказувати початок рядка запиту символом ?.
**Приклад 2**
// Change this number to fetch different post
const postId = 1;
fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`)
.then((response) => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then(post => console.log(post))
.catch(error => console.log(error));
====== Post (Створення) ======
Метод POST використовується для додавання нового ресурсу.
const postToAdd = {
title: "CRUD",
body: "CRUD is awesome!",
};
const options = {
method: "POST",
body: JSON.stringify(postToAdd),
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
};
fetch("", options)
.then((response) => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then(post => console.log(post))
.catch(error => console.log(error));
====== PUT і PATCH (Оновлення) ======
Використовуються для оновлення існуючих даних.
За HTTP-стандартом:
* PATCH замінює в наявному ресурсі значення, які були передані в тілі запиту. Значення ресурсу, які не передавались, лишаться без змін;
* PUT повністю замінює ресурс. Значення ресурсу, які не передавались, видаляються з ресурсу.
// Change value of id property to update different post
const postToUpdate = {
id: 1,
body: "CRUD is really awesome!",
};
const options = {
method: "PATCH",
body: JSON.stringify(postToUpdate),
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
};
fetch(`https://jsonplaceholder.typicode.com/posts/${postToUpdate.id}`, options)
.then((response) => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then(post => console.log(post))
.catch(error => console.log("ERROR:", error));
====== DELETE (Видалення) ======
використовується для видалення існуючих даних
const postIdToDelete = 1;
fetch(`https://jsonplaceholder.typicode.com/posts/${postIdToDelete}`, {
method: "DELETE",
})
.then((response) => {
if (!response.ok) {
throw new Error(response.status);
}
return response.json();
})
.then((deletedPost) => console.log(deletedPost))
.catch(error => console.log("Error:", error));