Перейти к содержимому
WEB TRICKS MASTER
Поддержать

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

Доброго времени суток, друзья. При разработке современных приложений (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 для получения самой последней и актуальной информации.

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

Оставить комментарий

Адрес почты не публикуется. Обязательные поля отмечены звёздочкой.

Вам может понравиться

Введите хотя бы два символа