Пояснення JavaScript Fetch API

JavaScript Fetch API надає зрозумілий та зручний спосіб для вашої веб-програми, що працює у браузері, здійснювати запити до зовнішніх ресурсів.

Він відрізняється простотою у використанні та використовує сучасний синтаксис JavaScript. Цей матеріал слугуватиме вам як довідник з використання Fetch API.

Що являє собою JavaScript Fetch API?

JavaScript Fetch API – це інтерфейс, наданий сучасними браузерами для здійснення запитів з клієнтського боку. Він пропонує альтернативу застарілому методу AJAX XMLHttpRequest.

Він доступний як глобальна функція під назвою `fetch`. При її виклику з необхідними параметрами, функція повертає проміс, який розв’язується у відповідь. За допомогою `fetch` ви можете ініціювати будь-які HTTP запити.

Переваги Fetch API у порівнянні з іншими методами

  • Він має більш простий та зрозумілий інтерфейс, який легко вивчити та застосовувати. Таким чином, ваш код стає більш охайним при використанні Fetch API. XMLHttpRequest є більш складним, і код з ним виглядає не так елегантно, як при використанні Fetch API.
  • Він підтримує проміси, що забезпечує можливість написання більш чистого асинхронного коду. XMLHttpRequest не має такої підтримки; замість цього необхідно додавати колбеки до обробників подій. Залежно від ваших особистих вподобань, ви можете надати перевагу JavaScript Fetch API.
  • Він вбудований безпосередньо в браузер. Це означає відсутність потреби в підключенні додаткових бібліотек для здійснення запитів. Додаткові бібліотеки можуть збільшити розмір вашого JavaScript-пакета і сповільнити роботу сайту.

Використання Fetch API

У цьому розділі ми розглянемо створення різних видів запитів, використовуючи JavaScript Fetch API. Для написання коду можна скористатися будь-яким редактором на ваш вибір. Важливо переконатися, що ви запускаєте код у веб-браузері. Я буду запускати код всередині тегу <script> у файлі HTML.

Простий GET-запит

Спершу, ми навчимося виконувати простий запит на отримання даних. Код для цього має наступну структуру:

fetch(url)

Наприклад, якщо нам потрібно отримати записи з JSON Placeholder API, це можна зробити так:

fetch('https://jsonplaceholder.typicode.com/posts');

Виклик цієї функції поверне проміс, який розв’яжеться з отриманою від API відповіддю або помилкою, якщо така виникне. Щоб отримати відповідь, ми будемо використовувати ключове слово `await`. Але `await` можна застосовувати лише всередині асинхронної функції.

Тому, ми обгорнемо виклик `fetch` асинхронною функцією та викличемо її. Якщо ця концепція для вас нова, рекомендую ознайомитися з детальним матеріалом про асинхронний JavaScript. А ось і приклад коду:

async function getData() {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    console.log(response);
}

getData();

Якщо запустити цей код, у консолі ви маєте отримати наступне:

Результат показує, що функція `fetch` повернула об’єкт `Response`. Цей об’єкт містить такі властивості, як статус, заголовки та тіло. Дані відповіді зберігаються у тілі у вигляді JSON-рядка. Отже, для отримання даних у вигляді JavaScript-об’єкта, нам необхідно витягти рядок та розпарсити JSON.

На щастя, об’єкт `Response` має зручний метод під назвою `json()`. Цей метод зчитує тіло відповіді та намагається розпарсити його як JSON-рядок. Він повертає проміс, що розв’язується з об’єктом, отриманим в результаті розбору JSON.

Однак, цей метод згенерує помилку, якщо тіло не є валідним JSON-рядком. Тому, ми повинні розпарсувати JSON лише тоді, коли відповідь має статус 200.

Отже, код для отримання записів буде виглядати так:

async function getData() {
    const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts"
    );

    if (response.status == 200) {
        const posts = await response.json();
        console.log(posts);
    } else {
        console.log("Сталася помилка:", response.status);
    }
}
getData();

Виконання цього коду дасть нам наступний результат:

Це масив, що містить 100 записів.

Для деяких API-кінцевих точок можуть знадобитися заголовки. Заголовки можуть використовуватися, наприклад, для авторизації. JavaScript Fetch API надає простий спосіб надсилання заголовків як частини запиту. Щоб задати заголовки, у виклик `fetch` потрібно передати об’єкт налаштувань.

fetch(url, options);

Отже, попередній приклад тепер виглядатиме наступним чином:

async function getData() {
    const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts", {
             headers: {
                 'x-auth': '<ваш токен авторизації>'
             }
         }
    );

    if (response.status == 200) {
        const posts = await response.json();
        console.log(posts);
    } else {
        console.log("Сталася помилка:", response.status);
    }
}
getData();

Оскільки JSONPlaceholder API не вимагає заголовка авторизації, наведений вище код працюватиме як і раніше. Проте, важливо розуміти можливість передачі заголовків.

Передача інших параметрів

Крім передачі заголовків, ви можете передати безліч інших параметрів функції `fetch`. Два параметри, які часто використовуються – це метод запиту та дані тіла запиту.

Ми використаємо POST запит до JSONPlaceholder API, щоб продемонструвати передачу обох параметрів. Ось приклад коду:

async function getData() {
    const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts", {
             method: 'POST',
             body: JSON.stringify({ 
                 title: 'Fetch API',
                 body: 'Lorem Ipsum',
                 userId: 1,
             })
        }
    );

    if (response.status == 200) {
        const posts = await response.json();
        console.log(posts);
    } else {
        console.log("Сталася помилка:", response.status);
    }
}
getData();

У об’єкті параметрів ми задали метод запиту та тіло як властивості. Для кожної властивості ми передали рядкові значення. Значення “POST” було вказано для методу, оскільки ми хочемо зробити POST запит. Для властивості `body` ми задали JSON-рядок. Цей JSON-рядок створюється шляхом створення рядкового представлення об’єкту з необхідними властивостями.

Запуск цього коду у браузері дасть такий результат:

Результатом є об’єкт, який містить `id`, отриманий від сервера. Ось корисне посилання для перегляду повного переліку можливих параметрів.

Помилки при використанні JavaScript Fetch API

#1. Помилки мережі

Під час виконання мережевих запитів часто виникають різні помилки. Функція `fetch` повертає проміс, який розв’язується з результатом або відхиляється, якщо виявлено мережеву помилку. Тому, для ефективної обробки мережевих помилок, наш код потрібно обернути в блок `try/catch`.

#2. Інші помилки

Крім мережевих помилок, ви також можете зіткнутися з іншими помилками, такими як 404, 403 та 500. Функція `fetch` не генерує помилку при виникненні подібних ситуацій. Тому необхідно перевіряти код статусу відповіді. Наприклад, у попередніх прикладах ми намагалися розпарсити тіло відповіді лише тоді, коли код статусу був 200.

#3. Помилки CORS

Іншою частою проблемою є помилки CORS. CORS – це Cross-Origin Resource Sharing (спільний доступ до ресурсів з різних джерел). Джерело – це унікальна комбінація протоколу, хоста та порту сервера. Наприклад, мій сайт може працювати на локальному хості на порту 5500 з протоколом HTTP. Таким чином, походженням цього веб-сайту буде http://localhost:5500.

Цей веб-сайт надсилає API запит до API https://jsonplaceholder.typicode.com, який має інше походження. Таким чином, ці два джерела – localhost та JSONPlaceholder – здійснюють обмін ресурсами. Це і є обмін ресурсами між джерелами. Проте, щоб це працювало, на сервері API має бути увімкнено CORS. І це не завжди так. Рішенням для обробки таких помилок є відправлення запитів через проксі-сервер з підтримкою CORS.

Підтримка браузерами

Fetch API – це відносно сучасна функціональність. За даними CanIUse.com, приблизно 95% користувачів у світі мають браузери з підтримкою Fetch API.

Висновок

JavaScript Fetch API – це синтаксично кращий та елегантніший спосіб для написання інтерфейсів, які надсилають запити до API. Враховуючи обмеження підтримки деякими браузерами, ви можете розглянути альтернативні HTTP-бібліотеки для клієнта.