Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Обработка тела запроса JS: HTTP Server

С чтением данных мы разобрались, давайте теперь попробуем их записывать. Создание новой записи в нашей телефонной книге через telnet будет таким:

telnet localhost 4000

Trying ::1...
Connected to localhost.
Escape character is '^]'.
POST /users.json HTTP/1.1
Host: localhost:4000
Connection: close
Content-Type: application/json
Content-Length: 38

{"name":"Bob","phone":"912-114-23-22"}
HTTP/1.1 201 Created
Content-Type: application/json
Date: Sat, 08 Oct 2016 10:23:06 GMT
Connection: keep-alive
Transfer-Encoding: chunked

5c
{"meta":{"location":"/users/15.json"},"data":{"name":"Bob","phone":"912-114-23-22","id":15}}
0

Отметим несколько важных моментов:

Добавлению новых данных в http соответствует глагол POST. Такой запрос не является идемпотентным (в соответствии с семантикой POST). Это означает, что повторная отправка данных приведёт к созданию дублей либо к ошибке (если внутри проверяются дубли).

Почти наверняка вы сталкивались с подобным поведением в интернете. Быстрый двойной клик на кнопке приводит к тому, что появляется, например, два комментария. А иногда, когда вы нажимаете f5, браузер спрашивает "вы точно хотите повторно отправить данные?". Это означает, что предыдущий запрос был POST.

Так как в случае POST запроса мы отправляем тело, нам нужно указать два заголовка:

  • Content-Type - чтобы сервер знал, как парсить наше тело
  • Content-Length - для определения конца запроса

Сервер

import http from 'http';

export default http.createServer((req, res) => {
  const body = [];

  req
    .on('data', chunk => body.push(chunk.toString()))
    .on('end', () => {
      const data = body.join();
      req.end(data);
    });
});

С точки зрения сервера body не является свойством объекта request, вместо этого сам request является eventEmitter и позволяет подписаться на событие data, которое вызывается каждый раз, когда приходит новая порция данных. Такой подход используется из-за того, что данные можно слать на сервер порциями (chunks).

После того, как запрос был полностью обработан, request инициирует событие end, внутри которого и нужно делать обработку поступивших данных и отвечать на запрос.

Обратите внимание на то, как идет работа с чанками данных. Перед тем, как попасть в массив body, делается преобразование в строку с помощью toString. Это связано с тем, что сырой чанк приходит как тип данных Buffer, который позволяет работать в том числе с данными в бинарном виде, а не только текстовом.

Валидация

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

Процесс проверки данных на корректность называется валидацией. В типичных веб-приложениях данные приходят из форм, которые заполняют пользователи или по API, и перед тем, как добавлять их к себе в хранилище, важно провалидировать эти данные. В самой валидации нет ничего сверхъестественного, это обычная проверка в коде, например, на то, что телефон приходит в строго определенном формате.

Ответ

Важно отвечать на POST запрос правильно, и это зависит от разных факторов. Выделим три ситуации (хотя, их больше на самом деле):

Успешный запрос (API)

Код ответа 201 (Created). В теле ответа обычно возвращают данные, такие как присвоенный идентификатор, что позволяет обратиться к вновь созданной сущности.

Успешный запрос (Web)

Необходимо обязательно сделать перенаправление (редирект) на другую страницу. Предпочтительно использовать код 303 (See Other).

Ошибка валидации

В этой ситуации код ответа должен быть 422 (unprocessable entity) в любом случае. Для разных видов приложения будет различаться только тело и его формат.


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

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

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

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
30 июня 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
30 июня 16 месяцев

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

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

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

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»