Владислав Калачев

Как получить данные с сервера? Fetch API. Разбираем работу fetch на примерах.

32 402

Доброго времени суток, друзья. При разработке современных приложений (SPA) нельзя обойтись без запросов клиентской части на сервер. Для работы с сетевыми запросами в JavaScript используется термин AJAX (Asynchronous JavaScript And XML), который включает в себя набор технологий: HTML, XHTML, CSS, DOM, JavaScript, XMLHttpRequest, XML, XSLT. Для создания самих запросов использовался API XMLHttpRequest, сейчас уже он является устаревшим. JavaScript обладает более современным интерфейсом Fetch API, который появился для работы с HTTP одновременно с Service Worker’ами. Основная проблема, которую позволил решить Fetch API это отказ от большого количества callback’ов при использовании XMLHttpRequest и переходу к Promise (Обещания).

Метод fetch

Fetch API предоставляет метод fetch() для работы с запросами. Данный метод поддерживается всеми современными браузерами. Для работы со старыми браузерами требуются полифиллы. Рассмотрим подробнее метод fetch и его параметры.

Пример:


fetch(url, [options])

Первый параметр предназначен для указания url адреса к запрашиваемому серверу. Этот параметр является строкой или строковым выражением (с возможностью указания в ней параметров). Второй параметр является объектом, в котором можно указать множество дополнительных опций. Если записывать fetch без второго параметра, то мы получим простой GET запрос.

Пример:


fetch('http://example.com/api/users')

Данная запись возвращает Promise, специальный объект хранящий свое состояние. Для того, чтобы понять как с ним работать, давайте рассмотрим его более подробно.

Видео на эту тему.

Promise

Для работы с Promise в JavaScript есть два способа:

— then/catch

— async/await

Начнем с then, этот метод предназначен для навешивая обработчиков на Promise. Для получения ответа требуется вызвать метод then два раза.

Пример:


fetch('http://example.com/api/users')
  .then((response) => {
    return response.json();
  })
  .then((data) => {
    console.log(data);
  });

В первом then происходит получение объекта Response. Данный объект хранит в себе состояние нашего запроса.

Пример:


{ 
 body: ReadableStream
,
 bodyUsed: false
,
 headers: Headers {},

 ok: true,
 
 redirected: false,

 status: 200,

 statusText: "",

 type: "basic"
 
 url: "http://example.com/api/users"

}

В примере выше можно посмотреть на основные поля ответа. Запрос выполнился со статусом 200 и состоянием ok, что означает true. Это означает что запрос был выполнен успешно и никаких ошибок не возникло.

Чтобы получить тело ответа, нужно воспользоваться специальным методом Response, посмотрим на его методы:

response.json() — декодирует ответ в JSON

response.text() — декодирует ответ в текст

response.formData() — вернет ответ в виде FormData

response.arrayBuffer() — вернет ответ в виде ArrayBuffer

response.blob() – вернет ответ в виде Blob

Важно. Можно использовать только один метод для обработки ответа. Повторный вызов другого метода приведет к ошибке.

Пример:


fetch(‘http://example.com/api/users')
  .then((response) => {
	response.text()
    return response.json(); // Error!
  })
  .then((data) => {
    console.log(data);
  });

В нашем примере мы преобразуем ответ в JSON формат.  После вызова первого then и применения метода объекта Response, в результате мы получаем Promise, для обработки которого снова требуется вызвать метод then. Результатом последующего вызова then будет получение тела нашего запроса.

Метод catch

Для обработки ошибок в Promise вместе с then используется метод catch.

Пример:


fetch('http://example.com/api/users')
  .then((response) => {
    response.text()
    return response.json(); // Error!
  })
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.log(error)
  })

Внутри catch достаточно вызвать колбэк функцию, в аргументе которой мы получим тело ошибки для ее дальнейшей обработки.

async/await

Второй, более современный и лаконичный способ работы с Promise является использование async/await. Перепишем наш предыдущий пример GET запроса.

Пример:


async function getUsers() {
 let response = await fetch('http://example.com/api/users');
 if (response.ok) {
   let data = await response.json();
   console.log(data);
   return data
 } else {
   alert('error', response.status);
 }
}

getUsers();

В данном примере для обработки ошибок идет проверка на состояние объекта Response. Для работы с ошибками в async/await существует более эстетичное решение с использованием конструкции try..catch

Пример:


async function getUsers() {
  try {
    let response = await fetch('http://example.com/api/users');
    let users = await response.json();
    return users;
  } catch(error) {
    alert(error);
  }
}

getUsers();

Заголовки запросов

Использование метода fetch дает возможность работать с заголовками. Для получения заголовка ответа, достаточно при получении объекта Response вызвать свойство headers и воспользовавшись методом .get() достать из него нужный заголовок.

Пример:


let response = await fetch('http://example.com/api/users');
response.headers.get('Content-Type');

Для передачи заголовка запроса, необходимо воспользоваться вторым параметром метода fetch и передать в него объект headers. Например, установим Content-Type со значением application/json.

Пример:


let response = fetch('http://example.com/api/users', {
  headers: {
    "Content-Type": "application/json"
  }
})

POST  запрос

Вот так плавно мы перешли к использованию второго параметра метода fetch. Помимо получения данных с сервера частой задачей является отправление данных на сервер. Для этого требуется указать в объекте опций поле method и передать тело запроса body (если используется json формат, а не передача значений через url параметры) с указанием заголовка в headers.

Пример:


let user = {
  name: 'Dima'
};

let response = await fetch('http://example.com/api/user', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  },
  body: JSON.stringify(user)
});

let result = await response.json();

В примере при получении объекта user используется JSON.stringify для преобразования значения в строку JSON. Заголовок «Content-Type»: «application/json; charset=utf-8» явно указывает передачу на сервер формата JSON.

Описание Options

Напоследок пройдем по всем опциям второго параметра fetch.


let response = fetch('http://example.com/api/user', {
  method: «GET"
  headers: {
     "Content-Type": "text/plain;charset=UTF-8"
  },
  body: undefined 
  referrer: "http://example.com/api/user",
  referrerPolicy: "no-referrer-when-downgrade",
  mode: "cors",
  credentials: "same-origin"
  cache: "default"
  redirect: "follow", 
  integrity: "", 
  keepalive: false,
  signal: undefined,
  window: window
})

method — этот параметр мы уже разбирали выше. В нем мы указываем заголовок метода, с которым будем отправлять запрос ( «GET», «POST», «PUT», «DELETE» и другие).

headers — заголовки запроса. Зависит от тела запроса и обычно ставится автоматически.

body — тело запроса. Может быть FormData, BufferSource, URLSearchParams или string.

referrer — данный параметр отвечает за установку HTTP-запроса заголовка Referer. Как правило он устанавливается самостоятельно, без явного его указания. Можно не отправлять заголовок Referer, указав его значение как пустую строку «».

referrerPolicy — этот параметр устанавливает общие правила для Referer. Для более подробной информации воспользуйтесь официальной спецификацией

mode — защита от отправки запросов на другой сервер. Mode имеет несколько значений:

 — «no-cors» — разрешение простых запросов на другой сервер;

 — «cors» — установлен по умолчанию. Позволяет делать запросы разреженной CORS политикой сервера;

 — «same-origin» — запрос на другие сервера запрещен.

credentials — данный параметр указывает должен ли fetch отправлять куки и авторизованные заголовки вместе с HTTP-запросом. Имеет следующие значения:

 — «omit» — всегда не отправлять

 — «same-origin» — по умолчанию, не отправлять для запросов на другой сервер

 — «include» — отправлять всегда

cache — этот параметр позволяет указывать использовать или не использовать стандартное HTTP-кэширование. Имеет следующие значения:

— «only-if-cached» — использовать ответ из HTTP-кэша. Если ответа нет, то ошибка.

— «force-cache» — использовать ответ из HTTP-кэша. Если ответа нет, то сделать обычный HTTP-запрос.

— «no-cache» — сохраняет ответ в HTTP-кэш.

— «reload» — не брать результат из HTTP-кэша.

— «no-store» — игнорировать HTTP-кэш

— «default» — стандартное поведение и использование HTTP-кэша по умолчанию.

redirect — отвечает за политику выполнения стандартного HTTP-редиректа. Имеет следующие значения:

 — «manual» — не следовать HTTP-редиректу

 — «error» — ошибка если произойдёт HTTP-редирект

 — «follow» — по умолчанию, следовать HTTP-редиректу

integrity — проверка соответствия ответа контрольной сумме.

keepalive — данный параметр указывает на то, что запрос может пережить страницу, которая его запросила. Имеет всего два значения (true/false)

signal — прерывание запроса.

window — можно передать глобальный объект window. В современных приложениях используется крайне редко.

Заключение

В данной статье мы подробно рассмотрели интерфейс Fetch API и его метод fetch. Поработали с Promises. Изучили обработчики обещаний, используя методы then/catch и специальный синтаксис async/await. Прошлись по основным параметрам метода fetch и подробно разобрали его опции. Надеюсь, что данный материал был вам полезен. Учитесь, думайте, пишите код. Удачного кодинга, друзья!

Полезные материалы:

https://learn.javascript.ru/fetch — документация Fetch

https://developer.mozilla.org/ru/docs/Web/API/Fetch_API/Using_Fetch — документация Fetch

Подписывайтесь на наш канал в Telegram и на YouTube для получения самой последней и актуальной информации.

Комментарии:

Как получить данные с сервера? Fetch API. Разбираем работу fetch на примерах.: 1 комментарий

  1. позволяет вам делать запросы, схожие с XMLHttpRequest (XHR). Основное отличие заключается в том, что Fetch API использует Promises (Обещания), которые позволяют использовать более простое и чистое API, избегать катастрофического количества callback’ов и необходимости помнить API для XMLHttpRequest. Fetch API стал доступен пользователям вместе с Service Worker ‘ами в global скоупе в Chrome 40, однако уже в версии 42 он станет доступен в скоупе window. Разумеется, для всех остальных браузеров, которые пока ещё не поддерживают fetch существует полифил от GitHub, который доступен уже сегодня. Первым делом мы проверяем статус ответа и проверяем, успешно ли выполнился запрос (ожидаем 200 статус). Если всё хорошо, то парсим ответ как JSON. Ответом

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *