Русский
Русский
English
Статистика
Реклама

Перевод Руководство по Express.js. Часть 3



Доброго времени суток, друзья!

Представляю вашему вниманию перевод второй части Руководства по Express веб-феймворку для Node.js автора Flavio Copes.

Предполагается, что вы знакомы с Node.js. Если нет, то прошу сюда.

Без дальнейших предисловий.

15. Шаблонизация


Express умеет работать с серверными шаблонизаторами (server-side template engines).

Шаблонизатор позволяет динамически генерировать HTML-разметку посредством передачи данных в представление (view).

По умолчанию Express использует шаблонизатор Pug, который раньше назывался Jade.

Несмотря на то, что с момента выхода последней версии Jade прошло почти 3 года, он все еще поддерживается в целях обеспечения обратной совместимости.

В новых проектах следует использовать Pug или другой шаблонизатор. Вот официальный сайт Pug: pugjs.org.

Среди других шаблонизаторов, можно назвать Handlebars, Mustache, EJS и др.

Использование Pug


Для использования Pug, его сначала нужно установить:

npm i pug 

Затем его следует добавить в Express:

const express = require('express')const app = express()app.set('view engine', 'pug')

После этого мы можем создавать шаблоны в файлах с расширением .pug.

Создадим представление about:

app.get('/about', (req, res) => {    res.render('about')})

И шаблон в views/about.pug:

p Привет от Pug 

Данный шаблон создаст тег p с текстом Привет от Pug.

Интерполировать переменные можно так:

app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})

p #{name} говорит привет

Подробнее о Pug мы поговорим в следующем разделе.

При использовании шаблонизатора для динамической генерации страниц можно столкнуться с некоторыми проблемами, особенно, когда возникает необходимость преобразовать HTML, например, в Pug. Для этого в сети существуют готовые решения. Вот одно из них: html-to-pug.com.

Использование Handlebars


Попробуем использовать Handlebars вместо Pug.

Устанавливаем его с помощью npm i handlebars.

В директории views создаем файл about.hbs следующего содержания:

{{name}} говорит привет 

Перепишем код Express:

const express = require('express')const app = express()const hbs = require('hbs')app.set('view engine', 'hbs')app.set('views', path.join(__dirname, 'views'))app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})app.listen(3000, () => console.log('Сервер готов'))

Вы также можете рендерить React на стороне сервера с помощью пакета express-react-views.

Устанавливаем данный пакет:

npm i express-react-views

Теперь вместо Handlebars укажем Express использовать express-react-views в качестве движка для обработки jsx-файлов:

const express = require('express')const app = express()app.set('view engine', 'jsx')app.engine('jsx', require('express-react-views').createEngine())app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})app.listen(3000, () => console.log('Сервер запущен'))

В директории views создаем файл about.jsx:

const React = require('react')class HelloMessage extends React.Component {    render() {        return <div>{this.props.name} говорит привет</div>    }}module.exports = HelloMessage

16. Справочник по Pug


Что такое Pug? Это шаблонизатор или движок для динамического рендеринга HTML-разметки, используемый Express по умолчанию.

Установка:

npm i pug

Настройка Express:

const path = require('path')cpnst express = require('express')const app = express()app.set('view engine', 'pug')app.set('views', path.join(__dirname, 'views'))app.get('/about', (req, res) => {    res.render('about', { name: 'Иван' })})

Шаблон (about.pug):

p #{name} говорит привет 

Передача функции, возвращающей значение:

app.get('about', (req, res) => {    res.render('about', { getName: () => 'Иван' })})

p #{getName()} говорит привет 

Добавление элементу идентификатора или класса:

p#title p.title 
Установка doctype:

doctype html 

Мета-теги:

html     head         meta(charset='utf-8')        meta(http-equiv='X-UA-Compatible', content='IE=edge')        meta(name='description', content='Описание')        meta(name='viewport', content='width=device-width, initial-scale=1')

Добавление скриптов или стилей:

html     head         link(rel="stylesheet", href="style.css")        script(src="script.js", defer)

Встроенные скрипты:

    script alert('тест')        script        (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]= function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date; e=o.createElement(i);r=o.getElementsByTagName(i)[0]; e.src='//www.google-analytics.com/analytics.js'; r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); ga('create','UA-XXXXX-X');ga('send','pageview');

Циклы:

ul     each color in ['Red', 'Green', 'Blue']        li= colorul     each color, index in ['Red', 'Green', 'Blue']        li= 'Номер цвета ' + index + ':' + color

Условия:

if name     h2 #{name} говорит привет else    h2 Привет if name    h2 #{name} говорит привет else if anotherName    h2 #{anotherName} говорит привет else    h2 Привет 

Переменные:

- var name = 'Иван'- age = 30 - var petr = { name: 'Петр' }- var friends = ['Иван', 'Петр']

Инкремент:

age++

Приваивание переменной элементу:

p= name span= age 

Перебор переменных:

for friend in friends     li= friendul     each friend in friends         li= friend 
Получение количества элементов:

p #{values.length}

While:

- var n = 0ul     while n <= 5        li= n++

Включение одного файла в другой:

include otherfile.pug 

Определение блоков.

Хорошо организованная система шаблонов предполагает создание базового шаблона и его расширение другими шаблонами по мере необходимости.

Базовый шаблон расширяется с помощью блоков:

html    head        link(rel="stylesheet", href="style.css")        script(src="script.js", defer)        body            block header                        block main                h1 Домашняя страница                p Добро пожаловать                        block footer

Расширение базового шаблона.

Шаблон расширяется с помощью ключевого слова extends:

extends home.pug 

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

extends home.pug block main     h1 Другая страница    p Привет     ul        li Раз элемент списка        li Два элемент списка 

Можно переопределять как один, так и несколько блоков. Те блоки, которые не переопределяются, сохраняют оригинальное содержимое.

Комментарии.

Видимые (сохраняются в разметке):

// однострочный комментарий//    многострочный    комментарий

Невидимые (удаляются при рендеринге):

//- однострочный комментарий//-     многострочный    комментарий

17. Middleware (промежуточный слой, промежуточное программное обеспечение)


Middleware это промежуточный слой между получением запроса от клиента и отправкой ему ответа. Другими словами, это функция, которая выполняет дополнительные операции в процессе маршрутизации после получения запроса и перед выполнением основных операций сервером.

Обычно, middleware применяется для обработки запроса/ответа либо для перехвата запроса перед его обработкой роутером. Middleware в общем виде выглядит так:

app.use((req, res, next) => {/* */})

Метод next() служит для передачи запроса следующему middleware, если в этом есть необходимость.

Если опустить next() в middleware, то обработка ответа завершится и он будет отправлен клиенту.

Middleware редко пишется вручную, как правило, в качестве таковых используются npm-пакеты.

Примером подобного пакета является cookie-parser, применяемый для преобразования куки в объект req.cookies. Данный пакет устанавливается с помощью npm i cookie-parser и используется следующим образом:

const express = require('express')const app = express()const cookieParser = require('cookie-parser')app.get('/', (req, res) => res.send('Привет!'))app.use(cookieParser())app.listen(3000, () => console.log('Сервер готов'))

Middleware может использоваться в определенном маршрутизаторе. Для этого он передается роутеру в качестве второго аргумента:

const myMiddleware = (req, res, next) => {    // ...     next()}app.get('/', myMiddleware, (req, res) => res.send('Привет!'))

Для того, чтобы сохранить данные, сформированные middleware, для их передачи другим middleware или обработчику запроса, используется объект Request.locals. Он позволяет записывать данные в текущий запрос:

req.locals.name = 'Иван'

18. Обработка статических файлов


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

const express = require('express')const app = express()app.use(express.static('public'))// ... app.listen(3000, () => console.log('Сервер готов'))

Если в директории public имеется файл index.html, он будет отправлен в ответ на запрос к localhost:3000.

19. Отправка файлов


Express предоставляет удобный метод для отправки файлов в ответ на запрос Reaponse.download().

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

Метод Response.download() позволяет отправлять файлы в ответ на запрос вместо отображения страницы:

app.get('/', (req, res) => res.download('./file.pdf'))

В контексте приложения это выглядит так:

const express = require('express')const app = express()app.get('/', (req, res) => res.download('./file.pdf'))app.listen(3000, () => console.log('Сервер готов'))

При отправке файла можно определить его название:

res.download('./file.pdf', 'some-custom-name.pdf')

Третим параметром рассматриваемого метода является колбэк, вызываемый после отправки файла:

res.download('./file.pdf', 'some-custom-name.pdf', error => {    if (error) {        // обрабатываем ошибку    } else {        console.log('Файл успешно отправлен')    }})

20. Сессии


По умолчанию запросы в Express являются одноразовыми, т.е. запросы не могут связываться между собой. Не существует способа определить, что повторный запрос отправлен тем же клиентом.

Пользователи не могут быть идентифицированы нативными средствами.

Вот где в игру вступают сессии.

После реализации названного механизма, каждому пользователю и сайту присваивается сессия, хранящая пользовательское состояние.

Мы будем использовать express-session, поддерживаемый командой Express.

Устанавливаем его:

npm i express-session

Инициализируем:

const session = require('express-session')

Добавляем в Express в качестве middleware:

const express = require('express')const session = require('express-session')const app = express()app.use(session(    'secret': '343ji43j4n3jn4jk3n'))

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

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

Сессия включается в состав запроса, доступ к ней можно получить через req.session:

app.get('/', (req, res, next) => {    // req.session })

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

req.sessions.name = 'Иван'console.log(req.sessions.name) // Иван 

При записи данные сериализуются (преобразуются в формат JSON), так что можно смело использовать вложенные объекты.

Сессии используются для передачи данных другим middleware или для их извлечения при последующих запросах.

Где хранятся сессионные данные? Это зависит от того, как настроен модуль express-session.

Такие данные могут храниться в:

  • памяти только при разработке
  • базе данных, например, MySQL или Mongo
  • кэше, например, Redis или Memcached

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

По идентификатору сервер осуществляет поиск хранящихся на нем данных.

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

Лучшим решением является Redis, однако, она требует дополнительной настройки инфраструктуры.

Другим популярным решением является пакет cookie-session. Он сохраняет данные в куки на стороне клиента. Данный способ использовать не рекомендуется, поскольку данные будут включаться в каждый запрос клиента и размер данных ограничен 4 Кб. Кроме того, обычные куки не подходят для хранения конфиденциальной информации. Существуют безопасные куки, передаваемые по протоколу HTTPS, но такие куки требуют дополнительной настройки с помощью прокси-сервера.

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

Следите за обновлениями. Благодарю за внимание и хороших выходных.
Источник: habr.com
К списку статей
Опубликовано: 12.09.2020 16:16:00
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Разработка веб-сайтов

Javascript

Программирование

Node.js

Nodejs

Node

Express.js

Expressjs

Express

Guide

Руководство

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru