Основы Node JS & Express (III). Теперь с параметрами, которые постоянно будут меняться
В этой главе я расскажу вам о том, как вы можете запустить простой HTTP-сервер на Node.js и начать обрабатывать запросы.
Модуль http для вашего Node.js-сервера
Когда вы начинаете создавать HTTP-приложения в Node.js, встроенные модули http/https - это то, с чем вы будете взаимодействовать.
Давайте создадим ваш первый HTTP-сервер на Node.js! Нам будет нужно подключить модуль http и привязать наш сервер к порту 3000 .
// содежимое index.js
const http = require("http")
const port = 3000
const requestHandler = (request, response) => {
console.log(request.url)
response.end("Hello Node.js Server!")
}
const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
})
Затем запускаем этот скрипт:
$ node index.js
Что нужно здесь отметить:
- requestHandler: эта функция будет вызываться каждый раз, когда на сервер придёт запрос. Если вы откроете в своём браузере адрес localhost:3000 , два сообщения появятся в консоли: одно для / и одно для favicon.ico .
- if (err) : обработка ошибок: если порт уже занят или есть какие-то другие причины, по которым сервер не может быть запущен, мы получим уведомление об этом.
Модуль http крайне низкоуровневый: создание сложного веб-приложения с использованием вышеприведенного фрагмента кода очень трудоемко. Именно по этой причине мы обычно выбираем фреймворки для работы над нашими проектами. Есть множество фреймворков, вот самые популярные:
- express
- hapi
- koa
- restify
В этой и следующих главах мы будем использовать Express, так как именно для него вы можете найти множество модулей в NPM.
Express
Быстрый, гибкий, минималистичный веб-фреймворк для Node.js - http://expressjs.com/
Добавление Express в ваш проект - это просто установка через NPM:
$ npm install express --save
После того, как вы установили Express, давайте посмотрим, как создать приложение аналогичное тому, что мы написали ранее:
const app = express()
const port = 3000
app.get(‘/’, (request, response) => {
response.send("Hello from Express!")
})
app.listen(port, (err) => {
if (err) {
return console.log("something bad happened", err)
}
console.log(`server is listening on ${port}`)
})
Самое большое различие, которое вы можете здесь заметить, заключается в том, что Express по умолчанию даёт вам роутер. Вам не нужно вручную разбирать URL, чтобы решить, что делать, вместо этого вы определяете маршрутизацию приложения с помощью app.get , app.post , app.put и так далее, а они уже транслируются в соответствующие HTTP-запросы.
Одна из самых мощных концепций, которую реализует Express - это паттерн Middleware.
Middleware - промежуточный обработчик
Вы можете думать о промежуточных обработчиках как о конвейерах Unix, но для HTTP-запросов.
На диаграмме вы можете увидеть, как запрос идёт через условное Express-приложение. Он проходит через три промежуточных обработчика. Каждый обработчик может изменить этот запрос, а затем, основываясь на вашей бизнес-логике, третий middleware отправит ответ, либо запрос попадёт в обработчик соответствующего роута.
На практике вы можете сделать это следующим образом:
Const express = require("express")
const app = express()
app.use((request, response, next) => {
console.log(request.headers)
next()
})
app.use((request, response, next) => {
request.chance = Math.random()
next()
})
app.get("/", (request, response) => {
response.json({
chance: request.chance
})
})
app.listen(3000)
Что следует здесь отметить:
- app.use: это то, как вы можете описать middleware. Этот метод принимает функцию с тремя параметрами, первый из которых является запросом, второй - ответом, а третий - коллбеком next . Вызов next сигнализирует Express о том, что он может переходить к следующему промежуточному обработчику.
- Первый промежуточный обработчик только логирует заголовки и мгновенно вызывает следующий.
- Второй добавляет дополнительное свойство к запросу - это одна из самых мощных функций шаблона middleware. Ваши промежуточные обработчики могут добавлять дополнительные данные к объекту запроса, который могут считывать/изменять middleware, расположенные ниже.
Обработка ошибок
Как и во всех фреймворках, правильная обработка ошибок имеет решающее значение. В Express вы должны создать специальный промежуточный обработчик - middleware с четырьмя входными параметрами:
Const express = require(‘express’)
const app = express()
app.get(‘/’, (request, response) => {
throw new Error(‘oops’)
})
app.use((err, request, response, next) => {
// логирование ошибки, пока просто console.log
console.log(err)
response.status(500).send(‘Something broke!’)
})
app.listen(3000)
Что следует здесь отметить:
- Обработчик ошибок должен быть последней функцией, добавленной с помощью app.use .
- Обработчик ошибок принимает коллбек next . Он может использоваться для объединения нескольких обработчиков ошибок.
Рендеринг HTML
Ранее мы рассмотрели, как отправлять JSON-ответы. Пришло время узнать, как отрендерить HTML простым способом. Для этого мы собираемся использовать пакет handlebars с обёрткой express-handlebars .
Сначала создадим следующую структуру каталогов:
├── index.js
└── views
├── home.hbs
└── layouts
└── main.hbs
После этого заполните index.js следующим кодом:
// index.js
const path = require("path")
const express = require("express")
const exphbs = require("express-handlebars")
const app = express()
app.engine(".hbs", exphbs({
defaultLayout: "main",
extname: ".hbs",
layoutsDir: path.join(__dirname, "views/layouts")
}))
app.set("view engine", ".hbs")
app.set("views", path.join(__dirname, "views"))
app.listen(3000)
Приведенный выше код инициализирует движок handlebars и устанавливает каталог шаблонов в views/layouts . Это каталог, в котором будут храниться ваши шаблоны.
После того, как вы сделали эту настройку, вы можете поместить свой начальный html в main.hbs . Чтобы всё было проще, давайте сразу перейдём к этому:
{{{body}}}
Вы можете заметить метку {{{body}}} - здесь будет размещен ваш контент. Давайте создадим home.hbs !
Hello {{name}}
Последнее, что мы должны сделать, чтобы заставить всё это работать, - добавить обработчик маршрута в наше приложение Express:
App.get("/", (request, response) => {
response.render("home", {
name: "John"
})
})
Метод render принимает два параметра:
- Первый - это имя шаблона.
- Второй - данные, необходимые для рендеринга.
Как только вы сделаете запрос по этому адресу, вы получите что-то вроде этого:
Hello John
Это всего лишь верхушка айсберга. Чтобы узнать, как добавить больше шаблонов (и даже частичных), обратитесь к официальной документации express-handlebars .
Отладка Express
В некоторых случаях вам может потребоваться выяснить, что происходит с Express, когда приложение работает. Для этого вы можете передать следующую переменную окружения в Express: DEBUG=express* .
Вы должны запустить свой Node.js HTTP-сервер, используя:
$ DEBUG=express* node index.js
Резюме
Вот как вы можете настроить свой первый HTTP-сервер на Node.js с нуля. Я рекомендую Express для начала, а затем поэкспериментируйте.
Основы Node JS & Express (III).
Разбираемся, что такое npm и для чего он нужен. Устанавливаем Express и шаблонизатор EJS. Делаем полную подготовительную работу и начинаем создавать свой собственный сайт на NodeJS.Теперь с параметрами, которые постоянно будут меняться.
Если нам нужно создать ссылку на некое значение, после /mews/значение . Оно будет меняться. Например: 23, part или любое др значение.App.get("/news/:id", function(req, res){ res.send("ID is - " + req.params.id); });
В зависимости от этого параметра мы можем брать данные из БД (базы данных) и выводить конкретную статью.
Нам нужен некий html файл куда мы будем передавать данные нашего id и в зависимости от этих данных выводить ту или иную информацию.
Нам нужен некий шаблонизатор .
Благодаря Express мы можем использовать несколько шаблонизаторов.
Поскольку EJS является дополнительным пакетом, то нам нужно его установить.
Нажать Enter
После этого он установится в наш проект.
Он позволяет передавать данные в различные шаблоны, причем эти шаблоны будут иметь расширение.ejs .
В этих шаблонах мы сможем выводить наш html код вместе с вставленным в него js кодом (переменными, выводить циклы и многое другое).
Будет такой шаблон страницы, который будет изменяться в зависимости от переданных в него данных.
Первое, что нам нужно сделать это указать какой view engine мы будем использовать.
View engine - по сути шаблонизатор.
Поскольку их существует огромное количество, а мы выбрали именно EJS, то мы должны его указать в нашем index.js файле.
Сразу после инициализации переменной app .
App.set("view-engine", "ejs");
Все файлы, которые мы будем отображать, по умолчанию будут искаться в папке views .
На том же уровне, где index.js создадим папку views .
В ней создадим новый файл news.ejs . Это будет некий шаблон, который мы будем наполнять.
В эти шаблоны мы можем помещать самый обычный html-код.
Новостная страница.
Для этого мне не нужно использовать метод.send или.sendFile , а мне потребуется метод render() .
Метод render() берет нужный файл (шаблон) в папке views и может отобразить его в браузере. Плюс в этот шаблон он может передать некие параметры.
Расширение в методе render() можно не указывать. Далее можно передать некие параметры в сам шаблон. Поэтому мы передаем вторым параметром - объект. В нем может быть большое количество свойств и значений.
Допустим, что мы решили передать некий параметр newsId со значением req.params.id - то есть значение будет как раз сам вызываемый id .
App.get("/news/:id", function(req, res){ render("news", {newsId: req.params.id}); });
Таким образом в шаблон news будет передано значение, которое будет называться newsId со значением id .
В файл news.ejs мы можем все это принять и отобразить.
Немного изменим наш файл news.ejs . В заголовок страницы будем выводить ID.
Все можно посмотреть в документации к шаблонизатору EJS (ссылка выше).
Новостная страница c ID = <%= newsId %>
Файл /views/news.ejs
Новостная страница c ID = <%= newsId %>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eaque numquam libero, veniam ipsum similique odit molestiae esse quia blanditiis magni debitis aliquam, pariatur nam quaerat quas nemo, facilis temporibus laboriosam.Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maiores enim vitae dolore nemo quas aliquam quia corrupti rerum ipsam ad nesciunt, architecto, pariatur officiis. Maxime iste ullam quibusdam, nobis voluptas!
Файл index.js
Let express = require("express"); let app = express(); app.set("view engine", "ejs"); app.get("/", function(req, res){ res.sendFile(__dirname + "/index.html"); }); app.get("/about", function(req, res){ res.sendFile(__dirname + "/about.html"); }); app.get("/news/:id", function(req, res){ res.render("news", {newsId: req.params.id}); }); app.listen(8080);
Мы можем передавать несколько параметров. Например:
App.get("/news/:id", function(req, res){ res.render("news", {newsId: req.params.id, newParam: 535 }); });
А в файле news.ejs выведем его на страницу, например так:
<%= newParam %>
Помимо этого мы можем передавать и собственные объекты. Например, создадим объект:
App.get("/news/:id", function(req, res){ let obj = { title:"Новость", id: 4}; res.render("news", {newsId: req.params.id, newParam: 535}); });
И этот объект мы тоже можем передавать. Вначале определяем название того, что будем передавать, а потом указываем что передаем.
Например:
App.get("/news/:id", function(req, res){ let obj = { title:"Новость", id: 4}; res.render("news", {newsId: req.params.id, newParam: 535, obj: obj }); });
Title = <%= obj.title %>
ID = <%= obj.id %>
<%= newParam %>
Передача в шаблон массива.
Создадим массив данных и выведем его с помощью цикла.App.get("/news/:id", function(req, res){ let obj = { title:"Новость", id: 4, paragraphs:["Параграф", "Обычный текст", "Числа: 3, 7, 24", 476] }; res.render("news", {newsId: req.params.id, newParam: 535, obj: obj}); });
Теперь в самом шаблоне мы просто выведем этот массив циклом:
-
<% obj.paragraphs.forEach(function(item) { %>
- <%= item %> <% }); %>
Статические файлы и промежуточное ПО.
Файлы, которые можно включить в другие файлы.
Сейчас у нас есть один шаблон - news.ejs , а представьте. что их много. Десятки. И вам потребуется внести изменения в какую-то часть кода, который встречается во всех этих файлах. Придется вносить множество изменений.Чтобы этого избежать, можно использовать файлы, которые можно включать в другие файлы. Например. Есть файл с шапкой сайта. И если нужно что-то изменить, то достаточно внести изменения только в один файл, так как к другим он просто подключается.
В папке шаблонов views создадим папку blocks , а в ней файл hrader.ejs .
Файл hrader.ejs
- На главную
- Про нас
- Новости
Теперь нам нужно этот файл подключить во всех шаблонах. Идем в файл news и сразу после открывающего тега body записываем:
<% include blocks/header.ejs %>
Путь указывается от папки views , поскольку шаблонизатор всегда начинает искать там.
Статические файлы.
Создадим новую папку на уровне index.js с названием public . В ней будут находиться все статические файлы. Это css-файлы, картинки, документы и пр. Все те файлы. которые будут вызываться с различных страниц нашего сайта.В этой папке создадим еще одну папку - css и уже в ней создадим файл style.css .
В него перенесем весь код стилей из файла index.ejs
В файлах.ejs подключаем стили:
Если теперь проверить, то ничего не произойдет. Стили не подключатся.
Для подключения статических файлов нам нужно использовать промежуточное программное обеспечение:
В файле index.js вверху, сразу за app.set , мы должны написать:
App.use("/public",);
И теперь, если мы где то будем использовать ссылку начинающуюся с /public сам NodeJS и Express будет понимать, что мы используем статические файлы и будет подключать все верно.
Вторым - где мы их ищем express.static("public") т. есть в папке /public .
Если обобщить, то в коде app.use("/public", express.static("public")); мы отслеживаем ту ссылку, которую прописываем в
Если бы у на было бы вот так:
То и в этом коде было бы:
App.use("/assets", express.static("public"));
В данном случае public указывает на папку!
Если так и оставить, то никаких изменений не произойдет. Файл подключится, потому что мы будем отслеживать ссылку assets .
App.use("/assets ", express.static("public "));
Для того, чтобы не путаться, обычно, делают ссылку и папку одного имени. Чаще всего это именно public .
Промежуточное ПО - это то, что мы делаем до того пока отправим какие-то данные на страницу (сервер).
В данном случае это и есть наше промежуточное ПО.
Создание HTML-формы и получение данных
Первое, что мы сделаем это добавим саму форму на наш сайт.Открываем файл about.ejs и сюда мы будем добавлять форму используя технологию bootstrap.
В окно поиска вводим Forms и на найденной странице копируем первую форму сверху.
Сохраним и запустим.
POST -запрос.
Так так мы будем выполнять POST -запрос, то нам необходимо добавить в форму несколько атрибутов.Method="post" - т.к POST -запрос
И action="" - это то куда нужно перенаправить пользователя после того,как он нажмет "Отправить". В нашем случае это: