Node js как разобрать post запрос

от admin

Anatomy of an HTTP Transaction

The purpose of this guide is to impart a solid understanding of the process of Node.js HTTP handling. We'll assume that you know, in a general sense, how HTTP requests work, regardless of language or programming environment. We'll also assume a bit of familiarity with Node.js EventEmitters and Streams . If you're not quite familiar with them, it's worth taking a quick read through the API docs for each of those.

Create the Server

Any node web server application will at some point have to create a web server object. This is done by using createServer .

The function that's passed in to createServer is called once for every HTTP request that's made against that server, so it's called the request handler. In fact, the Server object returned by createServer is an EventEmitter , and what we have here is just shorthand for creating a server object and then adding the listener later.

When an HTTP request hits the server, node calls the request handler function with a few handy objects for dealing with the transaction, request and response . We'll get to those shortly.

In order to actually serve requests, the listen method needs to be called on the server object. In most cases, all you'll need to pass to listen is the port number you want the server to listen on. There are some other options too, so consult the API reference.

Method, URL and Headers

When handling a request, the first thing you'll probably want to do is look at the method and URL, so that appropriate actions can be taken. Node.js makes this relatively painless by putting handy properties onto the request object.

The request object is an instance of IncomingMessage .

The method here will always be a normal HTTP method/verb. The url is the full URL without the server, protocol or port. For a typical URL, this means everything after and including the third forward slash.

Headers are also not far away. They're in their own object on request called headers .

It's important to note here that all headers are represented in lower-case only, regardless of how the client actually sent them. This simplifies the task of parsing headers for whatever purpose.

If some headers are repeated, then their values are overwritten or joined together as comma-separated strings, depending on the header. In some cases, this can be problematic, so rawHeaders is also available.

Request Body

When receiving a POST or PUT request, the request body might be important to your application. Getting at the body data is a little more involved than accessing request headers. The request object that's passed in to a handler implements the ReadableStream interface. This stream can be listened to or piped elsewhere just like any other stream. We can grab the data right out of the stream by listening to the stream's 'data' and 'end' events.

The chunk emitted in each 'data' event is a Buffer . If you know it's going to be string data, the best thing to do is collect the data in an array, then at the 'end' , concatenate and stringify it.

This may seem a tad tedious, and in many cases, it is. Luckily, there are modules like concat-stream and body on npm which can help hide away some of this logic. It's important to have a good understanding of what's going on before going down that road, and that's why you're here!

A Quick Thing About Errors

Since the request object is a ReadableStream , it's also an EventEmitter and behaves like one when an error happens.

An error in the request stream presents itself by emitting an 'error' event on the stream. If you don't have a listener for that event, the error will be thrown, which could crash your Node.js program. You should therefore add an 'error' listener on your request streams, even if you just log it and continue on your way. (Though it's probably best to send some kind of HTTP error response. More on that later.)

There are other ways of handling these errors such as other abstractions and tools, but always be aware that errors can and do happen, and you're going to have to deal with them.

What We've Got so Far

At this point, we've covered creating a server, and grabbing the method, URL, headers and body out of requests. When we put that all together, it might look something like this:

If we run this example, we'll be able to receive requests, but not respond to them. In fact, if you hit this example in a web browser, your request would time out, as nothing is being sent back to the client.

So far we haven't touched on the response object at all, which is an instance of ServerResponse , which is a WritableStream . It contains many useful methods for sending data back to the client. We'll cover that next.

HTTP Status Code

If you don't bother setting it, the HTTP status code on a response will always be 200. Of course, not every HTTP response warrants this, and at some point you'll definitely want to send a different status code. To do that, you can set the statusCode property.

There are some other shortcuts to this, as we'll see soon.

Setting Response Headers

Headers are set through a convenient method called setHeader .

When setting the headers on a response, the case is insensitive on their names. If you set a header repeatedly, the last value you set is the value that gets sent.

Explicitly Sending Header Data

The methods of setting the headers and status code that we've already discussed assume that you're using "implicit headers". This means you're counting on node to send the headers for you at the correct time before you start sending body data.

If you want, you can explicitly write the headers to the response stream. To do this, there's a method called writeHead , which writes the status code and the headers to the stream.

Once you've set the headers (either implicitly or explicitly), you're ready to start sending response data.

Sending Response Body

Since the response object is a WritableStream , writing a response body out to the client is just a matter of using the usual stream methods.

The end function on streams can also take in some optional data to send as the last bit of data on the stream, so we can simplify the example above as follows.

It's important to set the status and headers before you start writing chunks of data to the body. This makes sense, since headers come before the body in HTTP responses.

Another Quick Thing About Errors

The response stream can also emit 'error' events, and at some point you're going to have to deal with that as well. All of the advice for request stream errors still applies here.

Put It All Together

Now that we've learned about making HTTP responses, let's put it all together. Building on the earlier example, we're going to make a server that sends back all of the data that was sent to us by the user. We'll format that data as JSON using JSON.stringify .

Echo Server Example

Let's simplify the previous example to make a simple echo server, which just sends whatever data is received in the request right back in the response. All we need to do is grab the data from the request stream and write that data to the response stream, similar to what we did previously.

Now let's tweak this. We want to only send an echo under the following conditions:

  • The request method is POST.
  • The URL is /echo .

In any other case, we want to simply respond with a 404.

By checking the URL in this way, we're doing a form of "routing". Other forms of routing can be as simple as switch statements or as complex as whole frameworks like express . If you're looking for something that does routing and nothing else, try router .

Great! Now let's take a stab at simplifying this. Remember, the request object is a ReadableStream and the response object is a WritableStream . That means we can use pipe to direct data from one to the other. That's exactly what we want for an echo server!

We're not quite done yet though. As mentioned multiple times in this guide, errors can and do happen, and we need to deal with them.

To handle errors on the request stream, we'll log the error to stderr and send a 400 status code to indicate a Bad Request . In a real-world application, though, we'd want to inspect the error to figure out what the correct status code and message would be. As usual with errors, you should consult the Error documentation.

On the response, we'll just log the error to stderr .

We've now covered most of the basics of handling HTTP requests. At this point, you should be able to:

NodeJS. Как обрабатывать POST запросы.

Всем привет! В этой статье мы рассмотрим, как обрабатывать POST запросы в NodeJS.

POST запросы отличаются от GET запросов, которые мы рассматривали в прошлых статьях, тем, что данные в них передаются в закрытом виде. Это очень часто используется для передачи информации из форм. В прошлой статье мы как раз-таки создали форму, давайте ее и будем использовать для обработки POST запросов.

Поскольку такого удобного метода, как query(), для POST запросов нет, нам нужно установить дополнение под названием Body Parser. Найти вы его можете и скачать на сайте NPM.

После того, как вы его скачали и установили, подключите расширение в файле app.js:

var bodyParser = require('body-parser');

Теперь напишем следующий код:

var urlencodedParser = bodyParser.urlencoded();

Это middleware для POST запросов.

Теперь начнем получать и обрабатывать наш POST запрос:

app.post('/contact', urlencodedParser, function(req, res) <
res.render('contact-success', );
>);

Этот код делает следующее: когда мы отправляем форму, она ссылается на страницу /contact(т.е. на саму себя) и отправляет туда POST запрос. Мы этот POST запрос перехватываем, используем наш парсер для того, чтобы сразу получить данные в нормальном виде, а затем отрисовываем страницу по шаблону contact-success(мы далее создадим этот шаблон), куда передаем объект data, содержащий объект, который вернулся из ответа метода парсера body(), со свойствами, равными именам полей формы(who, department, email) и значениями, которые мы туда ввели. В общем-то, все просто и, благодаря парсеру, похоже на обработку GET запросов.

Теперь давайте создадим шаблон views/contact-success.ejs, куда скопируем весь код из файла contact.ejs. Удалим форму и в параграфе напишем следующее:

<p>Спасибо за обращение!</p>
<p>Вы связались с <%= data.who %> из <%= data.department %> отдела</p>
<p>Мы ответим вам на email: <%= data.email %></p>

Думаю, тут все понятно и пояснять не нужно.

А на этом сегодня все. Мы закончили изучение платформы NodeJS, и теперь у вас есть вся необходимая база знаний для того, чтобы создавать отличные приложения на ее основе. Однако, чтобы закрепить знания, мы создадим список дел на NodeJS в ближайшее время! Не пропустите!

Спасибо за внимание и удачи!

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Читать:
Cyberforum как удалить тему

Она выглядит вот так:

Комментарии ( 0 ):

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

Node.js
Обработка запроса POST в Node.js

Node.js использует потоки для обработки входящих данных.

Цитируя из документов,

Поток представляет собой абстрактный интерфейс для работы с потоковыми данными в Node.js. Модуль потока предоставляет базовый API, который упрощает сбор объектов, реализующих интерфейс потока.

Чтобы обрабатывать запрос в запросе POST, используйте объект request , который является читаемым потоком. Потоки данных испускаются как события data в объекте request .

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

Руководство по Node.js, часть 8: протоколы HTTP и WebSocket

Node.js — это серверная платформа. Основная задача сервера — как можно быстрее и эффективнее обрабатывать запросы, поступающие от клиентов, в частности — от браузеров. Восьмая часть перевода руководства по Node.js, которую мы публикуем сегодня, посвящена протоколам HTTP и WebSocket.

Что происходит при выполнении HTTP-запросов?

Поговорим о том, как браузеры выполняют запросы к серверам с использованием протокола HTTP/1.1.

Если вы когда-нибудь проходили собеседование в IT-сфере, то вас могли спросить о том, что происходит, когда вы вводите нечто в адресную строку браузера и нажимаете Enter. Пожалуй, это один из самых популярных вопросов, который встречается на подобных собеседованиях. Тот, кто задаёт подобные вопросы, хочет узнать, можете ли вы объяснить некоторые довольно-таки простые концепции и выяснить, понимаете ли вы принципы работы интернета.

Этот вопрос затрагивает множество технологий, понимать общие принципы которых — значит понимать, как устроена одна из самых сложных систем из когда-либо построенных человечеством, которая охватывает весь мир.

▍Протокол HTTP

Современные браузеры способны отличать настоящие URL-адреса, вводимые в их адресную строку, от поисковых запросов, для обработки которых обычно используется заданная по умолчанию поисковая система. Мы будем говорить именно об URL-адресах. Если вы введёте в строку браузера адрес сайта, вроде flaviocopes.com , браузер преобразует этот адрес к виду http://flaviocopes.com , исходя из предположения о том, что для обмена данными с указанным ресурсом будет использоваться протокол HTTP. Обратите внимание на то, что в Windows то, о чём мы будем тут говорить, может выглядеть немного иначе, чем в macOS и Linux.

▍Фаза DNS-поиска

Итак, браузер, начиная работу по загрузке данных с запрошенного пользователям адреса, выполняет операцию DNS-поиска (DNS Lookup) для того, чтобы выяснить IP-адрес соответствующего сервера. Символьные имена ресурсов, вводимые в адресную строку, удобны для людей, но устройство интернета подразумевает возможность обмена данными между компьютерами с использованием IP-адресов, которые представляют собой наборы чисел наподобие 222.324.3.1 (для протокола IPv4).

Сначала, выясняя IP-адрес сервера, браузер заглядывает в локальный DNS-кэш для того, чтобы узнать, не выполнялась ли недавно подобная процедура. В браузере Chrome, например, есть удобный способ посмотреть DNS-кэш, введя в адресной строке следующий адрес: chrome://net-internals/#dns .

Если в кэше ничего найти не удаётся, браузер использует системный вызов POSIX gethostbyname для того, чтобы узнать IP-адрес сервера.

▍Функция gethostbyname

Функция gethostbyname сначала проверяет файл hosts , который, в macOS или Linux, можно найти по адресу /etc/hosts , для того, чтобы узнать, можно ли, выясняя адрес сервера, обойтись локальными сведениями.

Если локальными средствами разрешить запрос на выяснение IP-адреса сервера не удаётся, система выполняет запрос к DNS-серверу. Адреса таких серверов хранятся в настройках системы.

Вот пара популярных DNS-серверов:

  • 8.8.8.8: DNS-сервер Google.
  • 1.1.1.1: DNS-сервер CloudFlare.

TCP и UDP — это два базовых протокола, применяемых в компьютерных сетях. Они расположены на одном концептуальном уровне, но TCP — это протокол, ориентированный на соединениях, а для обмена UDP-сообщениями, обработка которых создаёт небольшую дополнительную нагрузку на системы, процедура установления соединения не требуется. О том, как именно происходит обмен данными по UDP, мы говорить не будем.

IP-адрес, соответствующий интересующему нас доменному имени, может иметься в кэше DNS-сервера. Если это не так — он обратиться к корневому DNS-серверу. Система корневых DNS-серверов состоит из 13 серверов, от которых зависит работа всего интернета.

Надо отметить, что корневому DNS-серверу неизвестны соответствия между всеми существующими в мире доменными именами и IP-адресами. Но подобным серверам известны адреса DNS-серверов верхнего уровня для таких доменов, как .com, .it, .pizza, и так далее.

Получив запрос, корневой DNS-сервер перенаправляет его к DNS-серверу домена верхнего уровня, к так называемому TLD-серверу (от Top-Level Domain).

Предположим, браузер ищет IP-адрес для сервера flaviocopes.com . Обратившись к корневому DNS-серверу, браузер получит у него адрес TLD-сервера для зоны .com. Теперь этот адрес будет сохранён в кэше, в результате, если будет нужно узнать IP-адрес ещё какого-нибудь URL из зоны .com, к корневому DNS-серверу не придётся обращаться снова.

У TLD-серверов есть IP-адреса серверов имён (Name Server, NS), средствами которых и можно узнать IP-адрес по имеющемуся у нас URL. Откуда NS-сервера берут эти сведения? Дело в том, что если вы покупаете домен, доменный регистратор отправляет данные о нём серверам имён. Похожая процедура выполняется и, например, при смене хостинга.

Сервера, о которых идёт речь, обычно принадлежат хостинг-провайдерам. Как правило, для защиты от сбоев, создаются по несколько таких серверов. Например, у них могут быть такие адреса:

  • ns1.dreamhost.com
  • ns2.dreamhost.com
  • ns3.dreamhost.com

Теперь, после того, как нам удалось выяснить IP-адрес, стоящий за введённым в адресную строку браузера URL, мы переходим к следующему шагу нашей работы.

▍Установление TCP-соединения

Узнав IP-адрес сервера, клиент может инициировать процедуру TCP-подключения к нему. В процессе установления TCP-соединения клиент и сервер передают друг другу некоторые служебные данные, после чего они смогут обмениваться информацией. Это означает, что, после установления соединения, клиент сможет отправить серверу запрос.

▍Отправка запроса

Запрос представляет собой структурированный в соответствии с правилами используемого протокола фрагмент текста. Он состоит из трёх частей:

  • Строка запроса.
  • Заголовок запроса.
  • Тело запроса.
Строка запроса

Строка запроса представляет собой одну текстовую строку, в которой содержатся следующие сведения:

  • Метод HTTP.
  • Адрес ресурса.
  • Версия протокола.
Заголовок запроса

Заголовок запроса представлен набором пар вида поле: значение . Существуют 2 обязательных поля заголовка, одно из которых — Host , а второе — Connection . Остальные поля необязательны.

Заголовок может выглядеть так:

Поле Host указывает на доменное имя, которое интересует браузер. Поле Connection , установленное в значение close , означает, что соединение между клиентом и сервером не нужно держать открытым.

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

  • Origin
  • Accept
  • Accept-Encoding
  • Cookie
  • Cache-Control
  • Dnt

Заголовок запроса завершается пустой строкой.

Тело запроса

Тело запроса необязательно, в GET-запросах оно не используется. Тело запроса используется в POST-запросах, а также в других запросах. Оно может содержать, например, данные в формате JSON.

Так как сейчас речь идёт о GET-запросе, тело запроса будет пустым, с ним мы работать не будем.

▍Ответ

После того, как сервер получает отправленный клиентом запрос, он его обрабатывает и отправляем клиенту ответ.

Ответ начинается с кода состояния и с соответствующего сообщения. Если запрос выполнен успешно, то начало ответа будет выглядеть так:

Если что-то пошло не так, тут могут быть и другие коды. Например, следующие:

  • 404 Not Found
  • 403 Forbidden
  • 301 Moved Permanently
  • 500 Internal Server Error
  • 304 Not Modified
  • 401 Unauthorized
Разбор HTML-кода

После того, как браузер получает ответ сервера, в теле которого содержится HTML-код, он начинает его разбирать, повторяя вышеописанный процесс для каждого ресурса, который нужен для формирования страницы. К таким ресурсам относятся, например, следующие:

  • CSS-файлы.
  • Изображения.
  • Значок веб-страницы (favicon).
  • JavaScript-файлы.

О создании простого сервера средствами Node.js

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

Выполнение HTTP-запросов средствами Node.js

Для выполнения HTTP-запросов средствами Node.js используется соответствующий модуль. В приведённых ниже примерах применяется модуль https. Дело в том, что в современных условиях всегда, когда это возможно, нужно применять именно протокол HTTPS.

▍Выполнение GET-запросов

Вот пример выполнения GET-запроса средствами Node.js:

▍Выполнение POST-запроса

Вот как выполнить POST-запрос из Node.js:

▍Выполнение PUT-запросов и DELETE-запросов

Выполнение таких запросов выглядит так же, как и выполнение POST-запросов. Главное отличие, помимо смыслового наполнения таких операций, заключается в значении свойства method объекта options .

▍Выполнение HTTP-запросов в Node.js с использованием библиотеки Axios

Axios — это весьма популярная JavaScript-библиотека, работающая и в браузере (сюда входят все современные браузеры и IE, начиная с IE8), и в среде Node.js, которую можно использовать для выполнения HTTP-запросов.

Эта библиотека основана на промисах, она обладает некоторыми преимуществами перед стандартными механизмами, в частности, перед API Fetch. Среди её преимуществ можно отметить следующие:

  • Поддержка старых браузеров (для использования Fetch нужен полифилл).
  • Возможность прерывания запросов.
  • Поддержка установки тайм-аутов для запросов.
  • Встроенная защита от CSRF-атак.
  • Поддержка выгрузки данных с предоставлением сведений о ходе этого процесса.
  • Поддержка преобразования JSON-данных.
  • Работа в Node.js
Установка

Для установки Axios можно воспользоваться npm:

Того же эффекта можно достичь и при работе с yarn:

Подключить библиотеку к странице можно с помощью unpkg.com :

API Axios

Выполнить HTTP-запрос можно, воспользовавшись объектом axios :

Но обычно удобнее пользоваться специальными методами:

  • axios.get()
  • axios.post()

Axios предлагает отдельные методы и для выполнения других видов HTTP-запросов, которые не так популярны, как GET и POST, но всё-таки используются:

  • axios.delete()
  • axios.put()
  • axios.patch()
  • axios.options()
  • axios.head()
Запросы GET

Axios удобно использовать с применением современного синтаксиса async/await. В следующем примере кода, рассчитанном на Node.js, библиотека используется для загрузки списка пород собак из API Dog. Здесь применяется метод axios.get() и осуществляется подсчёт пород:

То же самое можно переписать и без использования async/await, применив промисы:

Использование параметров в GET-запросах

GET-запрос может содержать параметры, которые в URL выглядят так:

При использовании Axios запрос подобного рода можно выполнить так:

Того же эффекта можно достичь, настроив свойство params в объекте с параметрами:

Запросы POST

Выполнение POST-запросов очень похоже на выполнение GET-запросов, но тут, вместо метода axios.get() , используется метод axios.post() :

В качестве второго аргумента метод post принимает объект с параметрами запроса:

Использование протокола WebSocket в Node.js

WebSocket представляет собой альтернативу HTTP, его можно применять для организации обмена данными в веб-приложениях. Этот протокол позволяет создавать долгоживущие двунаправленные каналы связи между клиентом и сервером. После установления соединения канал связи остаётся открытым, что даёт в распоряжение приложения очень быстрое соединение, характеризующееся низкими задержками и небольшой дополнительной нагрузкой на систему.

Протокол WebSocket поддерживают все современные браузеры.

▍Отличия от HTTP

HTTP и WebSocket — это очень разные протоколы, в которых используются различные подходы к обмену данными. HTTP основан на модели «запрос — ответ»: сервер отправляет клиенту некие данные после того, как они будут запрошены. В случае с WebSocket всё устроено иначе. А именно:

  • Сервер может отправлять сообщения клиенту по своей инициативе, не дожидаясь поступления запроса от клиента.
  • Клиент и сервер могут обмениваться данными одновременно.
  • При передаче сообщения используется крайне малый объём служебных данных. Это, в частности, ведёт к низким задержкам при передаче данных.

▍Защищённая версия протокола WebSocket

Существует небезопасная версия протокола WebSocket (URI-схема ws:// ), которая напоминает, в плане защищённости, протокол http:// . Использования ws:// следует избегать, отдавая предпочтение защищённой версии протокола — wss:// .

▍Создание WebSocket-соединения

Для создания WebSocket-соединения нужно воспользоваться соответствующим конструктором:

После успешного установления соединения вызывается событие open . Организовать прослушивание этого события можно, назначив функцию обратного вызова свойству onopen объекта connection :

Для обработки ошибок используется обработчик события onerror :

▍Отправка данных на сервер

После открытия WebSocket-соединения с сервером ему можно отправлять данные. Сделать это можно, например в коллбэке onopen :

▍Получение данных с сервера

Для получения с сервера данных, отправленных с использованием протокола WebSocket, можно назначить коллбэк onmessage , который будет вызван при получении события message :

▍Реализация WebSocket-сервера в среде Node.js

Для того чтобы реализовать WebSocket-сервер в среде Node.js, можно воспользоваться популярной библиотекой ws. Мы применим её для разработки сервера, но она подходит и для создания клиентов, и для организации взаимодействия между двумя серверами.

Установим эту библиотеку, предварительно инициализировав проект:

Код WebSocket-сервера, который нам надо написать, довольно-таки компактен:

Здесь мы создаём новый сервер, который прослушивает стандартный для протокола WebSocket порт 8080 и описываем коллбэк, который, когда будет установлено соединение, отправляет клиенту сообщение ho! и выводит в консоль сообщение, полученное от клиента.

Вот рабочий пример WebSocket-сервера, а вот — клиент, который может с ним взаимодействовать.

Похожие статьи