# AJAX и Fetch API

## 1. Asynchronous JavaScript and XML <a href="#asynchronous-javascript-and-xml" id="asynchronous-javascript-and-xml"></a>

**AJAX** — метод отправки или запроса данных с последующим обновлением интерфейса по этим данным, без необходимости перезагрузки страницы. За счет этого уменьшается время отклика и веб-страница становится более интерактивной.

Несмотря на то, что в названии технологии присутствует XML, использовать его вовсе не обязательно. Под AJAX подразумевают любое общение с сервером без перезагрузки страницы.

В пример можно привести подгрузку данных:

* На веб-странице происходит событие (страница загружается, нажимается кнопка "Показать больше", отправляется форма и т. п.).
* На клиенте, с помощью JavaScript, реакцией на это событие выполнятся функция для работы с сервером, где создается и отправляется HTTP-запрос.
* Сервер получает и обрабатывает HTTP-запрос, отправляя обратно в ответе данные в JSON-формате.
* На клиенте, с помощью JavaScript, ответ от сервера обрабатывается, считываются данные и обновляется интерфейс.

## 2. Fetch API <a href="#fetch-api" id="fetch-api"></a>

[**Fetch API**](https://goo.gl/w17gH3) — предоставляет интерфейс, набор методов и свойств для отправки, получения и обработки ресурсов от сервера.

Это [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) нового поколения. Он предоставляет улучшенный интерфейс для составления запросов к серверу и построен на обещаниях (promise).

```bash
fetch(url, options)
Copy
```

* `url` — обязательный параметр - путь к данным которые вы хотите получить.
* `options` — необязательный параметр - объект настроек запроса. Содержит служебную информацию: метод (по умолчанию `GET`), заголовки, тело и т. д.
* Возвращает промис, который содержит ответ сервера.

```js
fetch('https://jsonplaceholder.typicode.com/users')
  .then(response => {
    //response handling
  })
  .then(data => {
    // data handling
  })
  .catch(error => {
    // error handling
  });
Copy
```

### 2.1. Response <a href="#response" id="response"></a>

В первый `then` передается экземпляр класса [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response), снабженный различными методами и свойствами. В нем содержится служебная информация о состоянии ответа сервера.

В зависимости от типа получаемого контента, используется различный метод парса.

* `Response.prototype.json()` - используется, когда от бекенда ожидаются данные в JSON-формате.
* `Response.prototype.text()` - используется, когда от бекенда ожидаются данные в простом текстовом формате, например `.csv` - формат хранения табличных данных в виде текстового файла.
* `Response.prototype.blob()` - используется, когда от бекенда ожидаются данные, описывающие файл, например изображение, аудио или видео.

```js
fetch('https://jsonplaceholder.typicode.com/users')
  .then(response => {
    return response.json();
  })
  .then(data => {
    // data handling
  })
  .catch(error => {
    // error handling
  });
Copy
```

### 2.2. Headers <a href="#headers" id="headers"></a>

[**Headers**](https://developer.mozilla.org/en-US/docs/Web/API/Headers) — позволяет выполнять различные действия в заголовках HTTP-запроса и ответа. Эти действия включают в себя извлечение, настройку, добавление и удаление заголовков (методы `append`, `has`, `get`, `set`, `delete`).

```js
const headers = new Headers({
  'Content-Type': 'application/json',
  'X-Custom-Header': 'custom value',
});

headers.append('Content-Type', 'text/bash');
headers.append('X-Custom-Header', 'custom value');
headers.has('Content-Type'); // true
headers.get('Content-Type'); // "text/bash"
headers.set('Content-Type', 'application/json');
headers.delete('X-Custom-Header');
Copy
```

Для составления заголовков запроса можно использовать просто литерал объекта со свойствами. В таком случае методов заголовков не будет, что зачастую и не требуется.

```js
const headers = {
  'Content-Type': 'application/json',
  'X-Custom-Header': 'custom value',
};
Copy
```

Запрос с использованием заголовков может выглядеть так.

```js
fetch('https://jsonplaceholder.typicode.com/users', {
  method: 'GET',
  headers: {
    Accept: 'application/json',
  },
}).then(response => {});
Copy
```

### 2.3. Ошибка при работе с асинхронным кодом <a href="#oshibka-pri-rabote-s-asinkhronnym-kodom" id="oshibka-pri-rabote-s-asinkhronnym-kodom"></a>

Разберем распространенную ошибку начинающих разработчиков, попытку использовать данные вне метода `then`, используем для этого предыдущий пример.

[Ссылка на пример в Codepen.io](https://codepen.io/goit-fe-adv/pen/veOrOa)

## 3. Вкладка Network <a href="#vkladka-network" id="vkladka-network"></a>

На вкладке `Network` отображаются все выполняющиеся на странице HTTP-запросы. Выбрав `XHR` (можно фильтровать по типу запроса), останутся только запросы к бекенду, и после нажатия кнопки, через некоторое время, отобразится запрос. Выбрав его, можно посмотреть служебную информацию и тело ответа на вкладках `Headers`, `Preview`, `Response` и `Timing`.

[Ссылка на пример в Codepen.io](https://codepen.io/goit-fe-adv/pen/gGaaqg)

![Вкладка Network](https://goit.global/javascript/ru/v1/module-12/images/http-request.png)

## 4. Работа с публичным RESTful API <a href="#rabota-s-publichnym-restful-api" id="rabota-s-publichnym-restful-api"></a>

Каждый API уникален, их тысячи, невозможно заучить код для работы с одним сервисом и использовать его для общения с другим. С другой стороны, RESTful API построены по принципам REST-архитектуры, а это значит, что можно понять принцип и методы работы, после чего, все что нужно сделать — это ознакомиться с документацией того сервиса, который необходимо использовать.

Для примера был выбран [API ПриватБанка](https://api.privatbank.ua/). Из документации берем URL для запроса информации о текущем курсе обмена валют.

```bash
https://api.privatbank.ua/p24api/pubinfo?exchange&json&coursid=11
Copy
```

Состоит из:

* `https://api.privatbank.ua/p24api` — endpoint, base URL, точка входа на API.
* `/pubinfo` — ресурс, к которому мы обращаемся
* `?` — говорит о том, что дальше идут параметры запроса
* `&` — используется для указания смыслового `И`, связывает параметры запроса

Параметры ответа из документации:

* `ccy` - код валюты
* `base_ccy` - код национальной валюты
* `buy` - курс покупки
* `sale` - курс продажи

[Ссылка на пример в Codepen.io](https://codepen.io/goit-fe-adv/pen/JrYGVE)
