Advertisement
  1. Code
  2. Web Development

Знакомство с фреймворком Connect

Scroll to top
Read Time: 10 min

Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)

Новичкам в NodeJS его API обычно кажется сложным. К счастью, многие разработчики создали фреймворки, которые упрощают работу с node. Connect - один из таких фреймворков. Он находится поверх API Node и рисует линию между комфортом и контролем.

Думайте о Connect как стеке middleware. С каждым запросом подключайте фильтры через слои middleware, каждый из которых имеет возможность обрабатывать HTTP-запрос. Когда T.J. Holowaychuk объявил Connect, он сказал, что существует два типа middleware. Первый - это фильтр.

Фильтры обрабатывают запрос, но они не реагируют на него (подумайте о регистрации сервера).

Другой тип - это провайдер, который отвечает на запрос. Вы можете включить столько слоев middleware, сколько захотите; запрос проходит через каждый уровень, пока один из middleware не ответит на запрос.


Основной синтаксис

Во-первых, вам нужно установить пакет Connect через npm:

Теперь создайте файл server.js и добавьте следующий код:

Переменная connect - это функция, которая возвращает новое приложение Connect. Итак, наш следующий шаг - создать это приложение:

Вам не нужно создавать переменную app для большинства ваших приложений. Функции, связанные с созданием приложения (connect() и use()), можно связать:

Функция use() добавляет в приложение слой middleware, а функция listen() сообщает нашему приложению начать прием соединений на указанном порту (3000 в этом примере).

Начнем с чего-то простого: logging. Код приложения Connect, использующего только middleware для ведения логов, довольно прост:

По умолчанию Node очень мало обрабатывает входящий запрос.

Добавьте этот код в свой файл и запустите сервер, выполнив команду node server.js. Перейдите к любому пути в вашем браузере и проигнорируйте результаты «Can not GET ...». Нам неинтересно, что сервер отправил обратно в браузер; нас интересует журнал сервера. Посмотрите на терминал, и вы увидите логи ваших запросов. Обязательно ознакомьтесь с документацией логера для получения информации о других его функциях и настройках.

Это был фильтр; теперь давайте посмотрим на провайдера. Простейшим провайдером является статический провайдер; он служит для статических файлов из указанной папки. Вот его синтаксис:

Вероятно, вы можете угадать цель переменной Node __dirname: это путь к текущему каталогу. Это middleware статически обслуживает все, что угодно, из папки public в текущем каталоге. Итак, создайте public/page.html и добавьте элемент <h1>. Перезагрузите сервер (node server.js) и перейдите к localhost:3000/page.html в своем браузере. Вы должны увидеть page.html в браузере.

Давайте теперь рассмотрим некоторые другие варианты middleware Connect.


Парсинг тела запроса

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

  • connect.json() анализирует тела запроса JSON (где content-type - application/json).
  • connect.urlencoded() разобрать x-www-form-urlencoded тело запроса.
  • connect.multipart() анализирует объекты запроса multipart/form-data.
  • connect.bodyParser() - это ярлык для включения всех трех из них.

Использование любого из этих фильтров дает вам возможность получить доступ к вашему анализируемому телу через request.body (мы поговорим о том, как быстро получить этот объект request).

Я думаю, что эти фильтры - хороший пример того, как настроить ваш контроль с помощью Connect. Вы можете использовать очень небольшую обработку, чтобы оптимизировать ваше приложение.


Парсинг файлов cookie и сессий

Файлы cookie и сеансы являются важной частью любого веб-приложения, и есть несколько middleware, которые помогают им управлять. Connection.cookieParser() анализирует файлы cookie для вас, и вы можете получить куки и их значения через объект request.cookies. Это более полезно, если вы добавите фильтр connect.session() в свое приложение. Этот фильтр требует, чтобы парсер cookie уже был на месте. Вот небольшой пример:

Каждая функция middleware, которую вы пишете, должна либо передать запрос на next уровень, либо ответить на запрос.

После cookieParser мы включаем фильтр session и передаем ему две опции:

  • secret создает подписанный файл cookie, который отслеживает сеанс.
  • cookie.maxAge определяет продолжительность жизни файла куки в миллисекундах; 30000 в этом коде составляет 30 секунд.

В финальном вызове use() мы передаем функцию, которая отвечает на запрос. Мы используем два свойства объекта request: req.session для данных сеанса и req.url для URL-адреса запроса.

Если приложение получает запрос для /name/some_name, оно сохраняет значение some_name в req.session.name. Все, что хранится в сеансе, можно получить в последующих запросах на длину нашего сеанса. Любые запросы, сделанные к /name/other, заменяют переменную сеанса, и любые запросы к другим URL-адресам выводят значение переменной сеанса и время, оставшееся для сеанса.

Итак, вы можете перейти к localhost:3000/name/your_name, а затем перейти на localhost:3000, чтобы увидеть your_name. Обновите страницу несколько раз и просмотрите отсчет секунд. По окончании сеанса вы увидите сообщение «no stored name» по умолчанию.

Я упомянул, что фильтр cookieParser должен появиться перед session.

Порядок включения имеет важное значение для middleware, потому что запрос передается по порядку от слоя к слою.

Поскольку для session нужны проанализированные данные cookie, запрос должен проходить через cookieParser перед session.

Я мог бы объяснить каждый другой встроенный компонент промежуточного программного обеспечения, но я просто упомянул еще несколько, прежде чем писать собственный код для взаимодействия с Connect.

  • compress: middlware для сжатия Gzip
  • basicAuth: базовая HTTP-аутентификация
  • directory: список каталогов 
  • errorHandler: гибкий обработчик ошибок

Написание собственного middleware

Вы только что научились писать свой собственный код с помощью Connect. Вот основной синтаксис еще раз:

Важны три параметра функции; они обеспечивают доступ к внешнему миру. Параметр req - это, конечно, объект запроса, а res - ответ. Третий параметр, next, является ключом к созданию функций, которые хорошо работают в стеке middleware. Это функция, которая передает запрос на следующее middleware в стеке:

В этом коде используются две функции middleware. Первая функция проверяет метод запроса, чтобы узнать, является ли это POST-запросом. Если это так, она отвечает так. В противном случае мы вызываем next() и передаем запрос следующей функции, которая отвечает всегда. Используйте curl для тестирования обоих слоев в терминале:

Если вам не нравится терминал, попробуйте этот удобный плагин Chrome.

Важно помнить, что каждая функция middleware, которую вы пишете, должна либо передать запрос на next уровень, либо ответить на запрос. Если у вашей функции есть несколько ветвей (через операторы if или другие условия), вы должны убедиться, что каждая ветка передает запрос или отвечает на него. Если ваше приложение зависает в браузере, возможно, потому, что вы забыли вызвать next() в какой-то момент.

Теперь, как насчет этих параметров request и response? Это те же объекты запроса и ответа, которые вы получаете при использовании «необработанного» сервера node:

Если вы раньше не использовали API-интерфейс Node, позвольте мне показать вам, что вы можете с ним сделать.


Объект запроса

Объект request фактически является объектом http.IncomingMessage, а его важные свойства перечислены ниже:

  • req.method сообщает вам, какой метод HTTP использовался.
  • req.url сообщает вам, какой URL был запрошен.
  • req.headers - это объект с именами и значениями заголовков.
  • req.query - это объект с любыми данными в строке запроса (для синтаксического анализа вам понадобится middleware connect.query()).
  • req.body - это объект данных формы (вам понадобится middleware для разбора тела).
  • req.cookies - это объект данных cookie (требуется разбор файлов cookie).
  • req.session является объектом данных сеанса (опять же, вам понадобится разбор cookie и middleware session)

Вы можете увидеть все это при работе со следующим кодом:

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

С помощью этих семи свойств вы можете управлять практически любым запросом, который вы получите. Я не думаю, что трейлеры часто используются (я никогда не видел их в своем опыте), но вы можете использовать req.trailers, если вы ожидаете их в своих запросах (трейлеры похожи на заголовки, но после тела).

Итак, как насчет вашего ответа?


Объект ответа

Необработанный объект ответа не обеспечивает роскошь, которую предоставляют библиотеки (например, Express). Например, вы не можете отвечать простым вызовом рендеринга на готовый шаблон - по крайней мере, не по умолчанию. В ответе очень мало, поэтому вам нужно заполнить все мелкие детали.

Мы начнем с кода состояния и заголовков ответов. Вы можете установить их все сразу, используя метод writeHead(). Вот пример из документов Node:

Если вам нужно индивидуально настроить заголовки, вы можете использовать метод setHeader():

Добавьте этот код в файл, запустите сервер и запросите его в браузере. У вас есть HTML! Теперь запустите:

И вы получите простой текст. Для JSON попробуйте следующее:

Все с одного и того же URL!

Используйте res.getHeader(name), если вам нужно знать, какие заголовки уже установлены. Вы также можете использовать res.removeHeader(name), чтобы удалить заголовок.

Конечно, ответ бесполезен без тела. Как вы видели в этом руководстве, вы можете записать куски данных в тело с помощью метода res.write(). Это принимает строку или буферный объект в качестве аргумента. Если это строка, вторым параметром является тип кодировки (по умолчанию используется utf8).

Метод res.end() закрывает тело, но вы можете передавать ему данные для записи в поток ответов. Это полезно в ситуациях, когда вам нужно выводить только одну строку.


Сторонние middleware

Сложно ответить на большие тела HTML в обычном старом node и Connect. Это хорошее место, чтобы использовать middleware. Вы можете найти список сторонних middleware в вики Connect Github. В качестве примера мы собираемся использовать пакет connect-jade, который позволяет нам отображать jade представления.

Сначала установите connect-jade:

Затем необходимо запросить и добавить его в качестве middleware. Вы хотите установить несколько значений по умолчанию:

Задайте корень как каталог, содержащий файлы отображений. Вы также можете установить defaults; это переменные, доступные во всех представлениях, если мы не переопределим их позже при вызове render().

Последняя функция в этом коде вызывает вызов res.render(). Этот метод предоставляется пакетом connect-jade.

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

Это путь к представлению, без пути, который мы определили при добавлении middleware, без расширения jade-файла. Для этого кода нам нужен шаблон views/index.jade для рендеринга. Мы будем держать это просто:

Если вы не знакомы с jade, у нас есть имена тегов отступа, чтобы создать структуру HTML. Знак равенства получает значение переменной JavaScript. Эти переменные исходят из defaults, которые мы установили, плюс (необязательный) второй объект параметра, переданный в res.render().

Есть много других сторонних middleware, но они работают аналогично друг другу. Вы устанавливаете их через npm, требуете их и вводите их в действие.


Модули как middleware

Если вы вникнете в работу Connect, вы обнаружите, что каждый слой на самом деле является модулем node - очень интеллектуальный дизайн. Если вы используете Connect для крупных приложений, было бы идеально написать ваш код в формате модуля Node. Возможно, у вас есть файл app.js:

И в вашем server.js:


Заключение

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

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.