Поиск по сайту:

Как использовать JavaScript Fetch API для получения данных


Введение

Было время, когда XMLHttpRequest использовался для выполнения запросов API. В нем не было промисов и не было чистоты кода JavaScript. Используя jQuery, вы можете использовать более чистый синтаксис jQuery.ajax().

Теперь у JavaScript есть собственный встроенный способ выполнения запросов к API. Это Fetch API, новый стандарт для выполнения запросов к серверу с помощью промисов, но который также включает дополнительные функции.

В этом руководстве вы создадите запросы GET и POST с помощью Fetch API.

Предпосылки

Для выполнения этого урока вам потребуется следующее:

  • Локальная среда разработки для Node.js. Следуйте инструкциям по установке Node.js и созданию локальной среды разработки.
  • Основное понимание программирования на JavaScript, о котором вы можете узнать больше из серии статей Как кодировать на JavaScript.
  • Понимание обещаний в JavaScript. Прочитайте цикл обработки событий, обратные вызовы, промисы и асинхронность/ожидание в JavaScript.

Шаг 1 — Начало работы с синтаксисом Fetch API

Один из подходов к использованию Fetch API заключается в передаче fetch() URL-адреса API в качестве параметра:

fetch(url)

Метод fetch() возвращает обещание. После метода fetch() добавьте метод Promise then():

fetch(url)
  .then(function() {
    // handle the response
  })

Если возвращаемое обещание равно resolve, выполняется функция в методе then(). Эта функция содержит код для обработки данных, полученных от API.

После метода then() добавьте метод catch():

fetch(url)
  .then(function() {
    // handle the response
  })
  .catch(function() {
    // handle the error
  });

API, который вы вызываете с помощью fetch(), может быть недоступен или могут возникнуть другие ошибки. Если это произойдет, будет возвращено обещание reject. Метод catch используется для обработки reject. Код внутри catch() будет выполнен, если при вызове API по вашему выбору возникнет ошибка.

Поняв синтаксис использования Fetch API, вы теперь можете перейти к использованию fetch() в реальном API.

Шаг 2 — Использование Fetch для получения данных из API

Следующие примеры кода будут основаны на JSONPlaceholder API. С помощью API вы получите десять пользователей и выведете их на страницу с помощью JavaScript. В этом руководстве будут извлекаться данные из JSONPlaceholder API и отображаться в элементах списка внутри авторского списка.

Начните с создания HTML-файла и добавления заголовка и ненумерованного списка с id авторов:

<h1>Authors</h1>
<ul id="authors"></ul>

Теперь добавьте теги script в конец вашего HTML-файла и используйте селектор DOM, чтобы получить ul. Используйте getElementById с authors в качестве аргумента:

<h1>Authors</h1>
<ul id="authors"></ul>

<script>
  const ul = document.getElementById('authors');
</script>

Помните, что authors — это id для ранее созданного ul.

Затем создайте list, который является DocumentFragment:

<script>
  // ...

  const list = document.createDocumentFragment();
</script>

Все добавленные элементы списка будут добавлены в list. DocumentFragment не является частью активной древовидной структуры документа. Преимущество этого заключается в том, что при изменении объектной модели документа не происходит перерисовки, влияющей на производительность.

Создайте постоянную переменную с именем url, которая будет содержать URL-адрес API, возвращающий десять случайных пользователей:

<script>
  // ...

  const url = 'https://jsonplaceholder.typicode.com/users';
</script>

Теперь, используя Fetch API, вызовите JSONPlaceholder API, используя fetch() с url в качестве аргумента:

<script>
  // ...

  fetch(url)
</script>

Вы вызываете Fetch API и передаете URL-адрес JSONPlaceholder API. Затем приходит ответ. Однако ответ, который вы получаете, — это не JSON, а объект с набором методов, которые можно использовать в зависимости от того, что вы хотите делать с информацией. Чтобы преобразовать возвращаемый объект в формат JSON, используйте метод json().

Добавьте метод then(), который будет содержать функцию с параметром response:

<script>
  // ...

  fetch(url)
    .then((response) => {})
</script>

Параметр response принимает значение объекта, возвращенного из fetch(url). Используйте метод json() для преобразования response в данные JSON:

<script>
  // ...

  fetch(url)
    .then((response) => {
      return response.json();
    })
</script>

Данные JSON еще нужно обработать. Добавьте еще один оператор then() с функцией, у которой есть аргумент с именем data:

<script>
  // ...

  fetch(url)
    .then((response) => {
      return response.json();
    })
    .then((data) => {})
</script>

Внутри этой функции создайте переменную с именем authors, которая установлена равной data:

<script>
  // ...

  fetch(url)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      let authors = data;
    })
</script>

Для каждого автора в authors вам нужно создать элемент списка, отображающий его имя. Метод map() подходит для этого шаблона:

<script>
  // ...

  fetch(url)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      let authors = data;

      authors.map(function(author) {

      });
    })
</script>

В вашей функции map создайте переменную с именем li, которая будет установлена равной createElement с помощью li (код HTML элемент) в качестве аргумента. Также создайте h2 для name и span для email:

<script>
  // ...

  fetch(url)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      let authors = data;

      authors.map(function(author) {
        let li = document.createElement('li');
        let name = document.createElement('h2');
        let email = document.createElement('span');
      });
    })
</script>

Элемент h2 будет содержать имя автора. Элемент span будет содержать адрес электронной почты author. Свойство innerHTML и интерполяция строк позволят вам сделать это:

<script>
  // ...

  fetch(url)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      let authors = data;

      authors.map(function(author) {
        let li = document.createElement('li');
        let name = document.createElement('h2');
        let email = document.createElement('span');

        name.innerHTML = `${author.name}`;
        email.innerHTML = `${author.email}`;
      });
    })
</script>

Затем соедините эти элементы DOM с помощью appendChild:

<script>
  // ...

  fetch(url)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      let authors = data;

      authors.map(function(author) {
        let li = document.createElement('li');
        let name = document.createElement('h2');
        let email = document.createElement('span');

        name.innerHTML = `${author.name}`;
        email.innerHTML = `${author.email}`;

        li.appendChild(name);
        li.appendChild(email);
        list.appendChild(li);
      });
    })

  ul.appendChild(list);
</script>

Обратите внимание, что каждый элемент списка добавляется к DocumentFragment list. После завершения map list добавляется к элементу неупорядоченного списка ul.

Выполнив обе функции then(), вы можете добавить функцию catch(). Эта функция запишет потенциальную ошибку в консоль:

<script>
  // ...

  fetch(url)
    .then((response) => {
      // ...
    })
    .then((data) => {
      // ...
    })
    .catch(function(error) {
      console.log(error);
    });

  // ...
</script>

Это полный код созданного вами запроса:

<h1>Authors</h1>
<ul id="authors"></ul>

<script>
  const ul = document.getElementById('authors');
  const list = document.createDocumentFragment();
  const url = 'https://jsonplaceholder.typicode.com/users';

  fetch(url)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      let authors = data;

      authors.map(function(author) {
        let li = document.createElement('li');
        let name = document.createElement('h2');
        let email = document.createElement('span');

        name.innerHTML = `${author.name}`;
        email.innerHTML = `${author.email}`;

        li.appendChild(name);
        li.appendChild(email);
        list.appendChild(li);
      });
    }).
    .catch(function(error) {
      console.log(error);
    });

  ul.appendChild(list);
</script>

Вы только что успешно выполнили запрос GET, используя API JSONPlaceholder и API Fetch. На следующем шаге вы будете выполнять POST-запросы.

Шаг 3 — Обработка POST-запросов

Fetch по умолчанию использует запросы GET, но вы можете использовать все другие типы запросов, изменять заголовки и отправлять данные. Давайте создадим POST-запрос.

Во-первых, включите константную переменную, содержащую ссылку на JSONPlaceholder API:

const url = 'https://jsonplaceholder.typicode.com/users';

Затем вам нужно установить свой объект и передать его в качестве второго аргумента функции выборки. Это будет объект с именем data с ключом name и значением Sammy (или вашим именем):

// ...

let data = {
  name: 'Sammy'
}

Поскольку это запрос POST, вам нужно указать это явно. Создайте объект с именем fetchData:

// ...

let fetchData = {

}

Этот объект должен включать три ключа: method, body и headers:

// ...

let fetchData = {
  method: 'POST',
  body: JSON.stringify(data),
  headers: new Headers({
    'Content-Type': 'application/json; charset=UTF-8'
  })
}

Ключ method будет иметь значение POST. body будет установлен равным формату JSON.stringify() только что созданного объекта data. headers будет иметь значение Content-Type: application/json; кодировка=UTF-8.

Интерфейс Headers — это свойство Fetch API, позволяющее выполнять действия над заголовками HTTP-запросов и ответов. Эта статья под названием «Как определить маршруты и методы HTTP-запросов в Express» может предоставить вам дополнительную информацию.

При наличии этого кода запрос POST можно выполнить с помощью Fetch API. Вы будете включать url и fetchData в качестве аргументов для вашего POST-запроса fetch:

// ...

fetch(url, fetchData)

Функция then() будет включать код, обрабатывающий ответ, полученный от JSONPlaceholder API:

// ...

fetch(url, fetchData)
  .then(function() {
    // Handle response you get from the API
  });

Это полный код созданного вами запроса:

const url = 'https://jsonplaceholder.typicode.com/users';

let data = {
  name: 'Sammy'
}

let fetchData = {
  method: 'POST',
  body: JSON.stringify(data),
  headers: new Headers({
    'Content-Type': 'application/json; charset=UTF-8'
  })
}

fetch(url, fetchData)
  .then(function() {
    // Handle response you get from the API
  });

Кроме того, вы можете передать fetch() объект Request.

const url = 'https://jsonplaceholder.typicode.com/users';

let data = {
  name: 'Sammy'
}

let request = new Request(url, {
  method: 'POST',
  body: JSON.stringify(data),
  headers: new Headers({
    'Content-Type': 'application/json; charset=UTF-8'
  })
});

fetch(request)
  .then(function() {
    // Handle response you get from the API
  });

При таком подходе request может использоваться как единственный аргумент для fetch(), заменяя url и fetchData.

Теперь вы знаете два метода создания и выполнения запросов POST с помощью Fetch API.

Заключение

Хотя Fetch API еще не поддерживается всеми браузерами, это отличная альтернатива XMLHttpRequest.

Если вы хотите узнать, как вызывать веб-API с помощью React, ознакомьтесь с этой статьей на эту тему.