====== Запроси до HTTP / Api ====== ====== fetch (відправка запиту) ====== Набір властивостей і методів, які дозволяють відправляти, отримувати та обробляти ресурси із сервера. 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));