JS

fetch

Fetch

JavaScript может отправлять сетевые запросы на сервер и подгружать новую информацию по мере необходимости.

Например, мы можем использовать сетевой запрос, чтобы:

  • Отправить заказ,
  • Загрузить информацию о пользователе,
  • Запросить последние обновления с сервера,
  • …и т.п.

AJAX

var getJSON = function(url) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();

        xhr.open('get', url, true);

        // browsers that support this feature automatically handle the JSON.parse()
        xhr.responseType = 'json'; // ответ будет в виде обьекта, а не строка

        xhr.onload = function() {
            var status = xhr.status;

            if (status === 200) {
                resolve(xhr.response);
            } else {
                reject(status);
            }
        };
        xhr.send();
    });
};

getJSON('data.json').then(function(data) {
    console.log('Success ', data);
}, function(status) {
    console.log('Something went wrong.', status);
});

Для сетевых запросов из JavaScript есть широко известный термин «AJAX»

fetch

Метод fetch() — современный подход. Он не поддерживается старыми (можно использовать полифил), но поддерживается всеми современными браузерами.

let promise = fetch(url, [options])
  • url – URL для отправки запроса.
  • options – дополнительные параметры: метод, заголовки и так далее.

Без options это простой GET-запрос, скачивающий содержимое по адресу url.

Браузер сразу же начинает запрос и возвращает промис, который внешний код использует для получения результата.

fetch

Промис завершается с ошибкой, если fetch не смог выполнить HTTP-запрос, например при ошибке сети или если нет такого сайта. HTTP-статусы 404 и 500 не являются ошибкой.

Мы можем увидеть HTTP-статус в свойствах ответа:

  • status – код статуса HTTP-запроса, например 200.
  • ok – логическое значение: будет true, если код HTTP-статуса в диапазоне 200-299.
let response = await fetch(url);

if (response.ok) { // если HTTP-статус в диапазоне 200-299
  // получаем тело ответа (см. про этот метод ниже)
  let json = await response.json();
} else {
  alert("Ошибка HTTP: " + response.status);
}

fetch

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

  • response.text() – читает ответ и возвращает как обычный текст,
  • response.json() – декодирует ответ в формате JSON,
  • response.formData() – возвращает ответ как объект FormData (разберём его в следующей главе),
  • response.blob() – возвращает объект как Blob (бинарные данные с типом),
  • response.arrayBuffer() – возвращает ответ как ArrayBuffer (низкоуровневое представление бинарных данных),
  • помимо этого, response.body – это объект ReadableStream, с помощью которого можно считывать тело запроса по частям. Мы рассмотрим и такой пример несколько позже.

fetch

async function getPost() {
    let url = 'http://localhost:3000/posts';

    let response = await fetch(url);

    if (response.ok) { // если HTTP-статус в диапазоне 200-299
        // получаем тело ответа (см. про этот метод ниже)
        let json = await response.json(); // читаем ответ в формате JSON
        console.log(json);
    } else {
        console.log("Ошибка HTTP: " + response.status);
    }
}

getPost();

Headers

Для установки заголовка запроса в fetch мы можем использовать опцию headers. Она содержит объект с исходящими заголовками, например:

let response = fetch(protectedUrl, {
  headers: {
    Authentication: 'secret'
  }
});

Headers

  • Accept-Charset, Accept-Encoding
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Connection
  • Content-Length
  • Cookie, Cookie2
  • Date
  • DNT
  • Expect
  • Host
  • Keep-Alive
  • Origin
  • Referer
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade
  • Via
  • Proxy-*
  • Sec-*

POST request

  • Для отправки POST-запроса или запроса с другим методом, нам необходимо использовать fetch параметры:

  • method – HTTP метод, например POST,
  • body – тело запроса, одно из списка:
    • строка (например, в формате JSON),
    • объект FormData для отправки данных как form/multipart,
    • Blob/BufferSource для отправки бинарных данных,
    • URLSearchParams для отправки данных в кодировке x-www-form-urlencoded, используется редко.

POST request

async function createPost() {
    let url = 'http://localhost:3000/posts';
    let post = {
        "title": "title 5",
        "author": "author 5",
    };
    let response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        },
        body: JSON.stringify(post)
    });

    if (response.ok) {
        let json = await response.json();
        console.log(json);
    } else {
        console.log("Ошибка HTTP: " + response.status);
    }
}

createPost();

Итого

Типичный запрос с помощью fetch состоит из двух операторов await:

let response = await fetch(url, options); // завершается с заголовками ответа
let result = await response.json(); // читать тело ответа в формате JSON

Или, без await:

fetch(url, options)
  .then(response => response.json())
  .then(result => /* обрабатываем результат */)

Итого

Параметры ответа:

  • response.status – HTTP-код ответа,
  • response.ok – true, если статус ответа в диапазоне 200-299.
  • response.headers – похожий на Map объект с HTTP-заголовками.

Итого

Методы для получения тела ответа:

  • response.text() – возвращает ответ как обычный текст,
  • response.json() – преобразовывает ответ в JSON-объект,
  • response.formData() – возвращает ответ как объект FormData (кодировка form/multipart, см. следующую главу),
  • response.blob() – возвращает объект как Blob (бинарные данные с типом),
  • response.arrayBuffer() – возвращает ответ как ArrayBuffer (низкоуровневые бинарные данные),

Итого

Опции fetch, которые мы изучили на данный момент:

  • method – HTTP-метод,
  • headers – объект с запрашиваемыми заголовками (не все заголовки разрешены),
  • body – данные для отправки (тело запроса) в виде текста, FormData, BufferSource, Blob или UrlSearchParams.

В следующих главах мы рассмотрим больше параметров и вариантов использования fetch.

JS

By Oleg Rovenskyi

JS

js fetch

  • 225