HTTP-запросы в Node.js с Fetch API

Из этого руководства вы узнаете, как делать HTTP-запросы в Node.js с помощью Fetch API
3 min read
Fetch API in NodeJS

API Fetch представляет собой новый официально поддерживаемый способ выполнения HTTP-запросов и получения локальных ресурсов в Node.js. Это означает, что вам больше не нужны внешние взаимосвязи HTTP-клиентов в вашем проекте. Все, что вам нужно сделать, — это научиться использовать Node Fetch API, о чем и идет речь в этом руководстве.

Здесь вы увидите:

  • Что такое Fetch API
  • Начало работы с Node Fetch API
  • Выполнение HTTP-запросов в Node.js с помощью Fetch API
  • Дополнительные опции и возможности

Давайте узнаем подробности!

Что такое Fetch API?

Fetch API представляет собой интерфейс JavaScript для локального получения ресурсов или их получения через сеть. В частности, он предоставляет глобальную функцию fetch(), которая упрощает выполнение асинхронных HTTP-запросов. Этот же способ также можно использовать для извлечения локальных файлов. API JavaScript Fetch представляет собой гибкую замену устаревшему API XMLHttpRequest.

Метод fetch () основан на объектах Request и Response. Требуется только один обязательный аргумент — локальный путь или URL-адрес ресурса, который вы хотите получить. Затем он также принимает некоторые дополнительные опции, включая CORS, HTTP-заголовок и настройки кеширования. В качестве асинхронного метода fetch() возвращает Promise , которое обрабатывает ответ, полученный сервером. Он представлен объектом Response, который поддерживает несколько способов доступа к телу содержимого и его анализа.

Вот как выглядит базовый вызов Fetch API:

fetch("https://httpbin.io/ip", {

  // optional configs...

}).then((response) => {

  // print the JSON response body

  console.log(response.json()) // {  "origin": "<YOUR_IP_ADDRESS>" }

})

Or if you prefer the equivalent async/await syntax, you can write:

const response = await fetch("https://httpbin.io/ip", {

  // optional configs...

})

// print the JSON response body

console.log(await response.json()) // { "origin": "<YOUR_IP_ADDRESS>" }

Начало работы с Node Fetch API

Fetch API уже много лет поддерживается основными браузерами. Тем не менее, он стала частью стандартной библиотеки Node.js только с версии 18.0.0, выпущенной в апреле 2022 года. В частности, Node Fetch API основан на реализации undici.

До версии Node.js 18 вы могли использовать функцию fetch(), включив ее в качестве экспериментальной функции или воспользовавшись библиотекой node-fetch npm, еще одной популярной реализацией Fetch API. Поскольку fetch() теперь является частью официальной стандартной библиотеки Node.js, ее можно использовать непосредственно в коде без импорта. Все, что вам нужно сделать, — это вызвать метод fetch() со следующим синтаксисом:

fetch(url, options)

URL-адрес обязателен и может содержать:

  • Путь к локальному ресурсу (например, movies.json) 
  • URL-адрес удаленной конечной точки или ресурса (например, https://httpbin.io/ip или https://example.com/movies.json)

Вместо этого options является необязательным объектом, который принимает следующие необязательные поля:

  • method: способ HTTP запроса, такой как “GET”, “POST”, “PUT”, “PATCH” и “DELETE”. По умолчанию используется значение «GET». 
  • заголовки: заголовки или литералы объектов, содержащие HTTP-заголовки, которые нужно добавить к вашему запросу. По умолчанию заголовок не установлен.
  • тело: объект, содержащий данные для использования в качестве тела вашего запроса. Обратите внимание, что запросы GET и HEAD не могут иметь тела.
  • режим: режим, используемый для запроса (например, «cors», «no-cors», «same-origin», «navigate» или «websocket»). По умолчанию установлено значение cors.
  • учетные данные: чтобы указать, должен ли браузер отправлять учетные данные или нет. Это должна быть одна из следующих строк: «omit», «same-origin» или «include».
  • redirect: определение способа обработки ответа на перенаправление HTTP. Это может быть follow («следовать»), error («ошибка») или manual («вручную»). По умолчанию установлено значение follow.
  • реферер: строка, содержащая реферер запроса. По умолчанию это пустая строка.
  • ReferrerPolicy: указывает политику реферера, которую следует использовать для запроса.
  • signal: экземпляр объекта AbortSignal, позволяющий прервать запрос через интерфейс AbortController.
  • priority: строка, указывающая приоритет текущего запроса Fetch по отношению к другим запросам того же типа. Он принимает значения high («высокий»), low («низкий») или auto («автоматический»). По умолчанию используется значение auto («автоматический»).

Ознакомьтесь с разделом параметров fetch () в официальной документации, чтобы узнать подробности.

Это пример запроса Node.js Fetch с объектом options:

const response = await fetch("https://your-domain.com/api/v1/users", {

  method: "POST",

  credentials: "include",

  headers: {

    "Content-Type": "application/json",

  },

  body: JSON.stringify({

    username: "jane-doe",

    email: "[email protected]"

    role: "superuser",

    age: 23,

    birthplace: "New York",

  }),

})

Обратите внимание, что данные тела должны соответствовать заголовку Content-Type.

Выполнение HTTP-запросов в Node.js с помощью Fetch API

Давайте теперь посмотрим на Node Fetch API в действии на реальных примерах запросов для самых популярных методов HTTP.

GET

Вот как можно выполнить запрос GET с помощью Fetch API:

const response = await fetch("https://your-domain.com/your-endpoint")

Как вы можете видеть, требуется всего одна строку кода. Это связано с тем, что fetch() выполняет запросы GET по умолчанию.

Затем вы можете получить доступ к содержимому ответа одним из следующих способов:

  • response.text(): возвращает Promise, в котором тело ответа выполнено в виде текста.
  • response.json(): возвращает Promise, который выполнен с помощью объекта, подвергшегося парсингу на основе ответа JSON.
  • response.blob(): возвращает Promise, в котором тело ответа выполнено в виде объекта Blob.
  • response.arrayBuffer (): возвращает Promise, в котором тело ответа выполнено в виде в качестве инстанса ArrayBuffer.
  • response.formData (): возвращает Promise, в котором тело ответа выполнено в виде объекта FormData.

Итак, код полного примера будет выглядеть так:

const response = await fetch("https://httpbin.io/ip")

const jsonResponseContent = await response.json() // { "origin": "<YOUR_IP_ADDRESS>" }

const origin = jsonResponseContent.origin // <YOUR_IP_ADDRESS>

Если ответ, возвращенный сервером, не в формате JSON, инструкция response.json() завершится ошибкой SyntaxError.

POST

Выполнение запроса POST с помощью вызова Node Fetch API занимает всего несколько строк:

const formData = new FormData()

formData.append("username", "serena-smith")

formData.append("email", "[email protected]")

const response = await fetch("https://example.com/api/v1/users", {

  method: "POST",

  body: formData,

})

Отправка запроса POST с помощью fetch() выполняется посредством указания данных для отправки на сервер в параметре body. Он может быть в нескольких форматах, включая JSON, FormData и текст. При отправке объекта FormData вам не нужно указывать заголовок Content-Type. В противном случае это обязательно. 

PUT

Выполнение запроса PUT с помощью Fetch API аналогично созданию POST: 

const response = await fetch("https://example.com/api/v1/users", {

  method: "PUT",

  credentials: "include",

  headers: {

    "Content-Type": "application/json",

  },

  body: JSON.stringify({

    username: "john-doe",

    email: "[email protected]"

    role: "regular-user",

    age: 47,

    birthplace: "Chicago",

  }),

})

Единственное отличие состоит в том, что вам нужно указать PUT в качестве настройки метода. Аналогичным образом можно отправить запрос PATCH, установив для него значение PATCH.

DELETE

Вот пример запроса HTTP DELETE с помощью fetch():

const response = await fetch("https://example.com/api/v1/users/45", {

  method: "DELETE",

})

Опять же, все сводится к настройке правильного метода HTTP. Об остальном позаботится реализация Fetch API.

Дополнительные опции и функции

Теперь, когда вы знаете, как использовать fetch() в стандартных сценариях, вы готовы изучить расширенные возможности Node Fetch API.

Настройка заголовков

fetch() позволяет настроить HTTP-заголовки запроса с помощью поля headers объекта options. В частности, заголовки принимают значения объекта Headers или литерал объекта с определенными строковыми значениями.

Предположим, вы хотите задать заголовок Content-Type и User-Agent в запросе fetch(). Вы можете использовать объект Headers, как показано ниже:

const customHeaders = new Headers()

customHeaders.append("Content-Type", "application/json")

customHeaders.append("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36")

const response = fetch("https://your-domain.com/your-endpoint", {

  headers: customHeaders,

  // other options...

})

В противном случае вы можете эквивалентно задать их с помощью литерала объекта:

const response = fetch("https://your-domain.com/your-endpoint", {

  headers: {

    "Content-Type": "application/json",

    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",

  },

  // other options...

})

Этот синтаксис более компактен и удобен для чтения.

Чтение заголовков

Если вы хотите прочитать HTTP-заголовки, установленные сервером в ответе, вы можете получить к ним доступ следующим образом:

const response = await fetch("https://your-domain.com/your-endpoint", {

  // optional configs...

})

// accessing the "Content-Type" response header

const responseHeaders = response.headers

const responseContentType = response.headers.get("Content-Type")

Поле response.headers возвращает объект Headers, из которого можно получить доступ к определенным заголовкам с помощью метода get(). 

Обработка ошибок Node Fetch API

Вызов Node.js Fetch API может завершиться неудачей только по двум причинам:

  • Исключение AbortError: выдается, когда запрос был преднамеренно прерван AbortController.
  • Исключение TypeError: это может произойти по нескольким причинам, таким как неправильное имя заголовка, неправильный URL-адрес или обычная сетевая ошибка. Узнайте больше о причинах в документации.

Важно понимать, что любой ответ 4xx или 5xx считается успешным запросом к Fetch API. Другими словами, ответ на ошибку, полученный сервером, не вызовет ошибок JavaScript. Причина такого поведения в том, что функция fetch() выполнила запрос, а сервер дал ответ. Концептуально это нельзя считать ошибкой с точки зрения сети. Ведь запрос был успешно выполнен.

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

try {

  const response = await fetch("https://your-domain.com/your-endpoint", {

    // optional configs...

  })

  if (response.ok) {

    // use the data returned by the server...

    // e.g., 

    // await response.json()

  } else {

    // handle 4xx and 5xx errors...

  }

} catch (error) {

  // handle network or abort errors...

}

Обратите внимание, что свойство ok из Response содержит значение true только в случае успешности запроса.

Отмена запроса Fetch

Fetch API поддерживает прерывание уже инициированных запросов через AbortController API. 

Чтобы остановить текущий запрос fetch(), сначала необходимо сгенерировать объект signal, как показано ниже:

const controller = new AbortController()

const signal = controller.signal

Then, specify it in the options object of your request:

const response = await fetch("https://your-domain.com/your-endpoint", {

  signal: signal,

  // other configs...

})

Теперь каждый раз, когда вы вызываете следующую инструкцию, ваш запрос будет прерван ошибкой AbortError:

controller.abort()

Имейте в виду, что сервер, возможно, уже получил запрос. В этом случае сервер все равно выполнит запрос, но ответ будет проигнорирован Node.js.

Поздравляем! Теперь вы стали профи по API Node.js Fetch!

Заключение

Из этой статьи вы узнали, что такое Fetch API и как его использовать в Node.js. При подробном рассмотрении вы начали с основ fetch(), а затем перешли к дополнительным параметрам и возможностям этой функции. С таким мощным HTTP-клиентом получение онлайн-данных становится простым. Например, вы можете использовать его для вызова наших конечных точек SERP API и начала очистки данных SERP.

Bright Data — крупнейшая в мире платформа веб-данных, обслуживающая более 20 000 компаний по всему миру. Обратитесь к одному из наших экспертов по данным, чтобы найти продукт, подходящий вам и для ваших потребностей в скрейпинге веб-страниц.