Зарегистрируйтесь для доступа к 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) в любом случае. Для разных видов приложения будет различаться только тело и его формат.


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

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

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

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

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

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

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

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

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

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

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

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

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

Есть вопрос или хотите участвовать в обсуждении?

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

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