Зарегистрируйтесь, чтобы продолжить обучение

GET-запрос JS: Синхронная асинхронность

Предположим, что мы хотим программно выполнить get запрос к Хекслету. В nodejs сделать это довольно просто:

import http from 'http';

http.get('http://ru.hexlet.io/my', res => {
  console.log(res.statusCode);
});

Вторым параметром передается колбек, который будет вызван после получения ответа. Он также принимает на вход объект response, который содержит в себе параметры ответа.

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

// response
{
  headers: /* ... */,
  statusCode: 301,
  statusMessage: 'Moved Permanently',
};

Также get позволяет передавать первым параметром не адрес, а набор опций, из которого будет составлен адрес. Такое бывает полезно, когда у нас нет готового адреса, но есть его части:

import http from 'http';

// headers, method, port, ...
const options = {
  hostname: 'ru.hexlet.io',
  path: 'my',
};

http.get(options, res => {
  console.log(res.statusCode);
});

Обо всех доступных опциях можно прочитать в официальной документации, а из самых распространенных мы выделим следующие:

  • headers — объект, в котором ключ — это название заголовка
  • method — например, GET
  • port
  • hostname
  • path

Body

В запросе выше не хватает одной важной детали: получение тела ответа. Тут нас поджидает небольшой сюрприз. Объект response не содержит внутри себя тело ответа. Связано это с тем, что ответ может приходить чанками, и response дает возможность получать эти чанки сразу и независимо друг от друга. С одной стороны, это более гибкая возможность, которая позволяет работать с большим телом, без того чтобы занимать много оперативной памяти; с другой стороны, для простых запросов приходится доставать тело немного более сложным способом, чем хотелось бы. Но, в конечном итоге, все сводится к понятному коду, который нужно просто запомнить.

http.get(url, res => {
  const body = [];
  res.on('data', chunk => {
    body.push(chunk.toString());
  }).on('end', () => {
    const html = body.join();
    console.log(html);
  });
});

Как видно из примера выше, объект response представляет из себя eventEmitter с событиями data и end. Первое вызывается после получения очередного чанка с данными, второе вызывается после того, как все данные пришли и нужно обозначить конец обработки.

Buffer

Из кода сбора чанков в body можно сделать вывод, что chunk – это не строка. Это действительно так, chunk – это объект типа Buffer, который предназначен для хранения потока байтов в виде массива фиксированного размера. Нужно это по той простой причине, что данные, передаваемые по http, не обязательно имеют текстовое представление. Возможна передача также и бинарных данных, таких как картинки, архивы и тому подобное.

const str = 'string as bytes';
const buffer = new Buffer(str, 'utf-8');
console.log(buffer);
// <Buffer 73 74 72 69 6e 67 20 61 73 20 62 79 74 65 73>
buffer.toString();
// string as bytes

Errors

Во время выполнения запроса может произойти все, что угодно. Библиотека http обрабатывает эти ошибки и кидает соответствующие исключения. К таким ошибкам относятся например:

  • Проблемы с DNS
  • Ошибки уровня tcp
  • Ошибки парсинга http ответа

Если для программы важно не завершаться в случае таких ошибок, то можно ловить событие error на объекте request, который возвращается после выполнения get запроса и производить желаемое действие:

import http from 'http';

const uri = 'http://ru.hexlet.io/my';

const req = http.get(uri, res => {
  console.log(res.statusCode);
});

req.on('error', e => {
  console.log(`Got error: ${e.message}`);
});

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»