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

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

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

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

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

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»
Andrey
ТСТопик закрыт
Andrei Zaporojan
ТСТопик закрыт
Решено
Отмечено как решение
Anatol Meshalkin
ТСТопик закрыт
Решено
Отмечено как решение
Yuriy Semenyuk
ТСТопик закрыт
Решено
Отмечено как решение
Daniyar Zhanakhmetov
ТСТопик закрыт
Решено
Отмечено как решение