Экспресс подробное руководство

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

Представляю вашему вниманию перевод второй части Руководства по 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= color

ul 
    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= friend

ul 
    each friend in friends 
        li= friend 

Получение количества элементов:

p #{values.length}

While:

- var n = 0

ul 
    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, но такие куки требуют дополнительной настройки с помощью прокси-сервера.

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

Следите за обновлениями. Благодарю за внимание и хороших выходных.

ExpressJS – Обзор

ExpressJS – это структура веб-приложений, которая предоставляет вам простой API для создания веб-сайтов, веб-приложений и серверных частей. С ExpressJS вам не нужно беспокоиться о протоколах низкого уровня, процессах и т. Д.

Что такое экспресс?

Express предоставляет минимальный интерфейс для создания наших приложений. Он предоставляет нам инструменты, необходимые для создания нашего приложения. Это гибкий инструмент , так как на npm доступно множество модулей, которые можно напрямую подключить к Express.

Express был разработан TJ Holowaychuk и поддерживается фондом Node.js и многочисленными участниками с открытым исходным кодом.

Зачем экспресс?

В отличие от своих конкурентов, таких как Rails и Django, которые имеют самоуверенный способ создания приложений, у Express нет «лучшего способа» что-либо сделать. Это очень гибкий и подключаемый.

мопс

Pug (ранее известный как Jade) – это краткий язык для написания HTML-шаблонов. Это –

  • Производит HTML
  • Поддерживает динамический код
  • Поддерживает повторное использование (СУХОЙ)

Это один из самых популярных языков шаблонов, используемых в Express.

MongoDB и Mongoose

MongoDB – это база данных документов с открытым исходным кодом, разработанная для простоты разработки и масштабирования. Эта база данных также используется для хранения данных.

Mongoose – это клиентский API для node.js, который облегчает доступ к нашей базе данных из нашего приложения Express.

ExpressJS – Окружающая среда

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

node --version
npm --version

Вы должны получить вывод, похожий на следующий.

v5.0.0
3.5.2

Теперь, когда у нас настроены Node и npm , давайте разберемся, что такое npm и как его использовать.

Диспетчер пакетов узлов (npm)

npm – менеджер пакетов для узла. Реестр npm – это общедоступная коллекция пакетов с открытым исходным кодом для Node.js, интерфейсных веб-приложений, мобильных приложений, роботов, маршрутизаторов и множества других потребностей сообщества JavaScript. npm позволяет нам получить доступ ко всем этим пакетам и установить их локально. Вы можете просмотреть список пакетов, доступных на npm на npmJS .

Как использовать npm?

Существует два способа установки пакета с использованием npm: глобально и локально.

  • Глобально – этот метод обычно используется для установки инструментов разработки и пакетов на основе CLI. Чтобы установить пакет глобально, используйте следующий код.

Глобально – этот метод обычно используется для установки инструментов разработки и пакетов на основе CLI. Чтобы установить пакет глобально, используйте следующий код.

npm install -g <package-name>
  • Локально – этот метод обычно используется для установки фреймворков и библиотек. Локально установленный пакет можно использовать только в том каталоге, в котором он установлен. Чтобы установить пакет локально, используйте ту же команду, что и выше, без флага -g .

Локально – этот метод обычно используется для установки фреймворков и библиотек. Локально установленный пакет можно использовать только в том каталоге, в котором он установлен. Чтобы установить пакет локально, используйте ту же команду, что и выше, без флага -g .

npm install <package-name>

Всякий раз, когда мы создаем проект с использованием npm, нам нужно предоставить файл package.json , в котором есть все подробности о нашем проекте. npm облегчает нам настройку этого файла. Давайте настроим наш проект развития.

Шаг 1 – Запустите свой терминал / cmd, создайте новую папку с именем hello-world и cd (создайте каталог) в нее –

Информация об инициации npm

Шаг 2 – Теперь, чтобы создать файл package.json с помощью npm, используйте следующий код.

npm init

Он попросит вас предоставить следующую информацию.

Информация об инициации npm

Просто продолжайте нажимать ввод и введите свое имя в поле «имя автора».

Шаг 3 – Теперь у нас есть настроенный файл package.json, далее мы установим Express. Чтобы установить Express и добавить его в наш файл package.json, используйте следующую команду –

npm install --save express

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

ls node_modules #(dir node_modules for windows)

Совет – Флаг – save может быть заменен флагом -S . Этот флаг гарантирует, что Express будет добавлен в качестве зависимости к нашему файлу package.json . Это имеет преимущество: в следующий раз, когда нам понадобится установить все зависимости нашего проекта, мы можем просто запустить команду npm install, и она найдет зависимости в этом файле и установит их для нас.

Это все, что нам нужно, чтобы начать разработку с использованием платформы Express. Чтобы облегчить процесс разработки, мы установим инструмент из npm, nodemon. Этот инструмент перезапускает наш сервер, как только мы вносим изменения в любой из наших файлов, в противном случае нам необходимо перезапускать сервер вручную после каждой модификации файла. Чтобы установить nodemon, используйте следующую команду –

npm install -g nodemon

Теперь вы можете начать работать на Express.

ExpressJS – Hello World

Мы приступили к разработке, теперь пришло время приступить к разработке нашего первого приложения с использованием Express. Создайте новый файл с именем index.js и введите в него следующее.

var express = require('express');
var app = express();

app.get('/', function(req, res){
   res.send("Hello world!");
});

app.listen(3000);

Сохраните файл, перейдите в свой терминал и введите следующее.

nodemon index.js

Это запустит сервер. Чтобы протестировать это приложение, откройте браузер и перейдите по адресу http: // localhost: 3000, и отобразится сообщение, как на следующем снимке экрана.

Привет, мир

Как работает приложение?

Первая строка импортирует Express в наш файл, у нас есть доступ к нему через переменную Express. Мы используем его для создания приложения и назначения его в var app.

app.get (маршрут, обратный вызов)

Эта функция сообщает, что делать, когда вызывается запрос get по заданному маршруту. Функция обратного вызова имеет 2 параметра: request (req) и response (res) . Объект запроса (req) представляет запрос HTTP и имеет свойства для строки запроса запроса, параметров, тела, заголовков HTTP и т. Д. Аналогично, объект ответа представляет ответ HTTP, который приложение Express отправляет, когда оно получает запрос HTTP.

res.send ()

Эта функция принимает объект в качестве входных данных и отправляет его запрашивающему клиенту. Здесь мы отправляем строку “Hello World!” ,

app.listen (порт, [хост], [отставание], [обратный вызов]])

Эта функция связывает и прослушивает соединения на указанном хосте и порте. Порт является единственным обязательным параметром здесь.

S.No. Аргумент и описание
1

порт

Номер порта, на который сервер должен принимать входящие запросы.

2

хозяин

Имя домена. Вы должны установить его при развертывании своих приложений в облаке.

3

отставание

Максимальное количество ожидающих соединений в очереди. По умолчанию это 511.

4

Перезвоните

Асинхронная функция, которая вызывается, когда сервер начинает прослушивать запросы.

порт

Номер порта, на который сервер должен принимать входящие запросы.

хозяин

Имя домена. Вы должны установить его при развертывании своих приложений в облаке.

отставание

Максимальное количество ожидающих соединений в очереди. По умолчанию это 511.

Перезвоните

Асинхронная функция, которая вызывается, когда сервер начинает прослушивать запросы.

ExpressJS – Маршрутизация

Веб-фреймворки предоставляют ресурсы, такие как HTML-страницы, скрипты, изображения и т. Д. По разным маршрутам.

Следующая функция используется для определения маршрутов в приложении Express –

app.method (путь, обработчик)

Этот МЕТОД может быть применен к любому из HTTP-глаголов – получить, установить, положить, удалить. Также существует альтернативный метод, который выполняется независимо от типа запроса.

Путь – это маршрут, по которому будет выполняться запрос.

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

var express = require('express');
var app = express();

app.get('/hello', function(req, res){
   res.send("Hello World!");
});

app.listen(3000);

Если мы запустим наше приложение и перейдем к localhost: 3000 / hello , сервер получит запрос get по маршруту “/ hello” , наше приложение Express выполнит функцию обратного вызова, прикрепленную к этому маршруту, и отправит “Hello World!” как ответ.

Привет

У нас также может быть несколько разных методов на одном и том же маршруте. Например,

var express = require('express');
var app = express();

app.get('/hello', function(req, res){
   res.send("Hello World!");
});

app.post('/hello', function(req, res){
   res.send("You just called the post method at '/hello'!n");
});

app.listen(3000);

Чтобы проверить этот запрос, откройте свой терминал и используйте cURL для выполнения следующего запроса:

curl -X POST "http://localhost:3000/hello"

Curl запрос

Express предоставляет специальный метод all для обработки всех типов методов http на определенном маршруте с использованием одной и той же функции. Чтобы использовать этот метод, попробуйте следующее.

app.all('/test', function(req, res){
   res.send("HTTP method doesn't have any effect on this route!");
});

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

Маршрутизаторы

Определение маршрутов, как описано выше, очень утомительно. Чтобы отделить маршруты от нашего основного файла index.js , мы будем использовать Express.Router . Создайте новый файл things.js и введите в него следующее.

var express = require('express');
var router = express.Router();

router.get('/', function(req, res){
   res.send('GET route on things.');
});
router.post('/', function(req, res){
   res.send('POST route on things.');
});

//export this router to use in our index.js
module.exports = router;

Теперь, чтобы использовать этот маршрутизатор в нашем index.js , введите следующее перед вызовом функции app.listen .

var express = require('Express');
var app = express();

var things = require('./things.js');

//both index.js and things.js should be in same directory
app.use('/things', things);

app.listen(3000);

Вызов функции app.use на маршруте «/ things» присоединяет маршрутизатор вещей к этому маршруту. Теперь любые запросы, которые наше приложение получает в «/ things», будут обрабатываться нашим маршрутизатором things.js. Маршрут «/» в things.js на самом деле является подчиненным маршрутом «/ things». Посетите localhost: 3000 / вещи /, и вы увидите следующий вывод.

Маршрутизатор Вещи

Маршрутизаторы очень помогают в разделении проблем и хранят соответствующие части нашего кода вместе. Они помогают в создании поддерживаемого кода. Вы должны определить свои маршруты, относящиеся к объекту, в одном файле и включить его, используя вышеуказанный метод, в свой файл index.js .

ExpressJS – методы HTTP

Метод HTTP предоставляется в запросе и определяет операцию, запрошенную клиентом. В следующей таблице перечислены наиболее часто используемые методы HTTP.

S.No. Метод и описание
1

ПОЛУЧИТЬ

Метод GET запрашивает представление указанного ресурса. Запросы с использованием GET должны только извлекать данные и не должны иметь никакого другого эффекта.

2

СООБЩЕНИЕ

Метод POST запрашивает, чтобы сервер принял данные, включенные в запрос, в качестве нового объекта / объекта ресурса, идентифицированного URI.

3

ПОЛОЖИЛ

Метод PUT запрашивает, чтобы сервер принял данные, включенные в запрос, как модификацию существующего объекта, идентифицированного URI. Если он не существует, метод PUT должен его создать.

4

УДАЛЯТЬ

Метод DELETE запрашивает, чтобы сервер удалил указанный ресурс.

ПОЛУЧИТЬ

Метод GET запрашивает представление указанного ресурса. Запросы с использованием GET должны только извлекать данные и не должны иметь никакого другого эффекта.

СООБЩЕНИЕ

Метод POST запрашивает, чтобы сервер принял данные, включенные в запрос, в качестве нового объекта / объекта ресурса, идентифицированного URI.

ПОЛОЖИЛ

Метод PUT запрашивает, чтобы сервер принял данные, включенные в запрос, как модификацию существующего объекта, идентифицированного URI. Если он не существует, метод PUT должен его создать.

УДАЛЯТЬ

Метод DELETE запрашивает, чтобы сервер удалил указанный ресурс.

Это самые распространенные методы HTTP. Чтобы узнать больше о методах, посетите http://www.tutorialspoint.com/http/http_methods.htm .

ExpressJS – Создание URL

Теперь мы можем определять маршруты, но они являются статическими или фиксированными. Чтобы использовать динамические маршруты, мы ДОЛЖНЫ предоставить различные типы маршрутов. Использование динамических маршрутов позволяет нам передавать параметры и обрабатывать их.

Вот пример динамического маршрута –

var express = require('express');
var app = express();

app.get('/:id', function(req, res){
   res.send('The id you specified is ' + req.params.id);
});
app.listen(3000);

Чтобы проверить это, перейдите на http: // localhost: 3000/123 . Следующий ответ будет отображаться.

Создание URL 1

Вы можете заменить «123» в URL-адресе на что-либо еще, и это изменение будет отражено в ответе. Более сложный пример вышесказанного –

var express = require('express');
var app = express();

app.get('/things/:name/:id', function(req, res) {
   res.send('id: ' + req.params.id + ' and name: ' + req.params.name);
});
app.listen(3000);

Чтобы проверить приведенный выше код, перейдите по адресу http: // localhost: 3000 / things / tutorialspoint / 12345 .

URL Building 2

Вы можете использовать объект req.params для доступа ко всем параметрам, которые вы передаете в URL. Обратите внимание, что выше 2 являются разными путями. Они никогда не будут пересекаться. Также, если вы хотите выполнить код, когда вы получаете «/ вещи», вам нужно определить его отдельно.

Маршруты, соответствующие шаблону

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

var express = require('express');
var app = express();

app.get('/things/:id([0-9]{5})', function(req, res){
   res.send('id: ' + req.params.id);
});

app.listen(3000);

Обратите внимание, что это будет соответствовать только запросам, которые имеют 5-значный длинный идентификатор . Вы можете использовать более сложные регулярные выражения для сопоставления / проверки ваших маршрутов. Если ни один из ваших маршрутов не соответствует запросу, вы получите сообщение «Cannot GET <your-request-route>» в качестве ответа. Это сообщение должно быть заменено страницей 404 не найден, используя этот простой маршрут –

var express = require('express');
var app = express();

//Other routes here
app.get('*', function(req, res){
   res.send('Sorry, this is an invalid URL.');
});
app.listen(3000);

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

Например, если мы определяем те же маршруты, что и выше, при запросе с допустимым URL-адресом отображается следующий вывод.

Правильное регулярное выражение

В случае неверного запроса URL-адреса отображается следующий вывод.

Неверное регулярное выражение (404)

ExpressJS – Middleware

Функции промежуточного программного обеспечения – это функции, которые имеют доступ к объекту запроса (req) , объекту ответа (res) и следующей функции промежуточного программного обеспечения в цикле запроса-ответа приложения. Эти функции используются для изменения объектов req и res для таких задач, как разбор тел запросов, добавление заголовков ответов и т. Д.

Вот простой пример функции промежуточного программного обеспечения в действии:

var express = require('express');
var app = express();

//Simple request time logger
app.use(function(req, res, next){
   console.log("A new request received at " + Date.now());
   
   //This function call is very important. It tells that more processing is
   //required for the current request and is in the next middleware
   function/route handler.
   next();
});

app.listen(3000);

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

A new request received at 1467267512545

Чтобы ограничить его конкретным маршрутом (и всеми его подчиненными маршрутами), укажите этот маршрут в качестве первого аргумента app.use () . Например,

var express = require('express');
var app = express();

//Middleware function to log request protocol
app.use('/things', function(req, res, next){
   console.log("A request for things received at " + Date.now());
   next();
});

// Route handler that sends the response
app.get('/things', function(req, res){
   res.send('Things');
});

app.listen(3000);

Теперь, когда вы запрашиваете какой-либо подчиненный маршрут «/ вещей», только тогда он будет записывать время.

Заказ звонков промежуточного программного обеспечения

Одна из самых важных вещей в промежуточном программном обеспечении в Express – это порядок, в котором они записаны / включены в ваш файл; порядок, в котором они выполняются, учитывая, что маршрут совпадает, также необходимо учитывать.

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

var express = require('express');
var app = express();

//First middleware before response is sent
app.use(function(req, res, next){
   console.log("Start");
   next();
});

//Route handler
app.get('/', function(req, res, next){
   res.send("Middle");
   next();
});

app.use('/', function(req, res){
   console.log('End');
});

app.listen(3000);

Когда мы запускаем «/» после запуска этого кода, мы получаем ответ как « Средний» и на нашей консоли –

Start
End

Следующая диаграмма обобщает то, что мы узнали о промежуточном программном обеспечении –

Промежуточное

Теперь, когда мы рассмотрели, как создать собственное промежуточное ПО, давайте обсудим некоторые из наиболее часто используемых промежуточных программ, созданных сообществом.

Стороннее промежуточное программное обеспечение

Список стороннего промежуточного программного обеспечения для Express доступен здесь . Ниже приведены некоторые из наиболее часто используемых промежуточного программного обеспечения; мы также узнаем, как их использовать / монтировать –

тело-анализатор

Это используется для анализа тела запросов, к которым прикреплены полезные данные. Чтобы смонтировать парсер тела, нам нужно установить его с помощью npm install –save body-parser и, чтобы смонтировать его, включите в ваш index.js следующие строки:

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

//To parse URL encoded data
app.use(bodyParser.urlencoded({ extended: false }))

//To parse json data
app.use(bodyParser.json())

Чтобы просмотреть все доступные опции для body-parser, посетите его страницу github.

печенье-анализатор

Он анализирует заголовок Cookie и заполняет req.cookies объектом, ключом которого являются имена файлов cookie. Чтобы смонтировать парсер cookie, нам нужно установить его с помощью npm install –save cookie-parser и, чтобы его смонтировать, включите в ваш index.js следующие строки:

var cookieParser = require('cookie-parser');
app.use(cookieParser())

экспресс-сессия

Создает промежуточное программное обеспечение сеанса с заданными параметрами. Мы обсудим его использование в разделе «Сессии».

У нас есть много других сторонних промежуточных программ в ExpressJS. Тем не менее, мы обсудили только несколько важных здесь.

ExpressJS – шаблоны

Мопс – движок шаблонов для Экспресса. Движки шаблонов используются для устранения загромождения кода нашего сервера с помощью HTML, дико объединяя строки с существующими шаблонами HTML. Pug – очень мощный движок шаблонов, который имеет множество функций, включая фильтры, включает в себя, наследование, интерполяцию и т. Д. Есть много оснований для этого.

Чтобы использовать Pug с Express, нам нужно установить его,

npm install --save pug

Теперь, когда Pug установлен, установите его как движок шаблонов для вашего приложения. Вам не нужно «требовать» этого. Добавьте следующий код в ваш файл index.js .

app.set('view engine', 'pug');
app.set('views','./views');

Теперь создайте новый каталог с именем views. Внутри этого создайте файл с именем first_view.pug и введите в него следующие данные.

doctype html
html
   head
      title = "Hello Pug"
   body
      p.greetings#people Hello World!

Чтобы запустить эту страницу, добавьте следующий маршрут в ваше приложение –

app.get('/first_template', function(req, res){
   res.render('first_view');
});

Вы получите вывод как – Hello World! Мопс преобразует эту очень простую на вид разметку в HTML. Нам не нужно отслеживать закрытие наших тегов, не нужно использовать ключевые слова class и id, лучше использовать ‘.’ и «#», чтобы определить их. Приведенный выше код сначала преобразуется в –

<!DOCTYPE html>
<html>
   <head>
      <title>Hello Pug</title>
   </head>
   
   <body>
      <p class = "greetings" id = "people">Hello World!</p>
   </body>
</html>

Мопс способен на гораздо большее, чем просто упрощение разметки HTML.

Важные особенности мопса

Давайте теперь рассмотрим несколько важных особенностей мопса.

Простые теги

Теги вложены в соответствии с их отступом. Как и в приведенном выше примере, тег <title> был вставлен в тег <head> , поэтому он был внутри него. Но тег <body> был на том же отступе, поэтому он был родным тегом <head> .

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

Чтобы поместить текст внутри тега, у нас есть 3 метода –

  • Пространство разделено

Пространство разделено

h1 Welcome to Pug
  • Трубопроводный текст

Трубопроводный текст

div
   | To insert multiline text, 
   | You can use the pipe operator.
  • Блок текста

Блок текста

div.
   But that gets tedious if you have a lot of text.
   You can use "." at the end of tag to denote block of text.
   To put tags inside this block, simply enter tag in a new line and 
   indent it accordingly.

Комментарии

Pug использует тот же синтаксис, что и JavaScript (//) для создания комментариев. Эти комментарии преобразуются в комментарии html (<! – comment ->). Например,

//This is a Pug comment

Этот комментарий преобразуется в следующее.

<!--This is a Pug comment-->

Атрибуты

Для определения атрибутов мы используем разделенный запятыми список атрибутов в скобках. Атрибуты класса и ID имеют специальные представления. Следующая строка кода описывает определение атрибутов, классов и идентификатора для данного HTML-тега.

div.container.column.main#division(width = "100", height = "100")

Эта строка кода преобразуется в следующую.

<div class = "container column main" id = "division" width = "100" height = "100"></div>

Передача значений в шаблоны

Когда мы визуализируем шаблон Pug, мы можем фактически передать ему значение из нашего обработчика маршрута, который мы затем можем использовать в нашем шаблоне. Создайте новый обработчик маршрута со следующим.

var express = require('express');
var app = express();

app.get('/dynamic_view', function(req, res){
   res.render('dynamic', {
      name: "TutorialsPoint", 
      url:"http://www.tutorialspoint.com"
   });
});

app.listen(3000);

И создайте новый файл представления в каталоге представлений, названный dynamic.pug , со следующим кодом –

html
   head
      title=name
   body
      h1=name
      a(href = url) URL

Откройте localhost: 3000 / dynamic_view в вашем браузере; Вы должны получить следующий вывод –

Переменные в шаблоне

Мы также можем использовать эти переданные переменные в тексте. Чтобы вставить переданные переменные в текст тега, мы используем синтаксис # {variableName} . Например, в приведенном выше примере, если мы хотим добавить приветствия из TutorialsPoint, мы могли бы сделать следующее.

html
   head
      title = name
   body
      h1 Greetings from #{name}
      a(href = url) URL

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

Templating Inter

Conditionals

Мы также можем использовать условные операторы и циклические конструкции.

Рассмотрим следующее –

Если пользователь вошел в систему, на странице должно отображаться «Привет, пользователь», а если нет, то ссылка «Вход / Регистрация» . Чтобы достичь этого, мы можем определить простой шаблон как –

html
   head
      title Simple template
   body
      if(user)
         h1 Hi, #{user.name}
      else
         a(href = "/sign_up") Sign Up

Когда мы визуализируем это, используя наши маршруты, мы можем передать объект, как в следующей программе:

res.render('/dynamic',{
   user: {name: "Ayush", age: "20"}
});

Вы получите сообщение – Привет, Аюш . Но если мы не передадим объект или не передадим его без ключа пользователя, мы получим ссылку для регистрации.

Включить и компоненты

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

Создайте 3 представления с помощью следующего кода –

HEADER.PUG

div.header.
   I'm the header for this website.

CONTENT.PUG

html
   head
      title Simple template
   body
      include ./header.pug
      h3 I'm the main content
      include ./footer.pug

FOOTER.PUG

div.footer.
   I'm the footer for this website.

Создайте маршрут для этого следующим образом –

var express = require('express');
var app = express();

app.get('/components', function(req, res){
    res.render('content');
});

app.listen(3000);

Перейдите на localhost: 3000 / компоненты, вы получите следующий вывод –

шаблонные компоненты

include также может использоваться для включения открытого текста, CSS и JavaScript.

Есть много других особенностей мопса. Но это выходит за рамки этого урока. Вы можете дополнительно исследовать Мопса в Мопсе .

ExpressJS – Обслуживание статических файлов

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

app.use(express.static('public'));

Примечание. Express ищет файлы относительно статического каталога, поэтому имя статического каталога не является частью URL-адреса.

Обратите внимание, что корневой маршрут теперь установлен на ваш публичный каталог, поэтому все загружаемые вами статические файлы будут считаться публичными как корневые. Чтобы проверить, что это работает нормально, добавьте любой файл изображения в ваш новый общедоступный каталог и измените его имя на « testimage.jpg ». В ваших представлениях создайте новое представление и включите этот файл как –

html
   head
   body
      h3 Testing static file serving:
      img(src = "/testimage.jpg", alt = "Testing Image

Вы должны получить следующий вывод –

Пример статических файлов

Несколько статических каталогов

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

var express = require('express');
var app = express();

app.use(express.static('public'));
app.use(express.static('images'));

app.listen(3000);

Префикс виртуального пути

Мы также можем предоставить префикс пути для обслуживания статических файлов. Например, если вы хотите предоставить префикс пути, такой как «/ static» , вам нужно включить следующий код в ваш файл index.js:

var express = require('express');
var app = express();

app.use('/static', express.static('public'));

app.listen(3000);

Теперь, когда вам нужно включить файл, например, файл скрипта с именем main.js, находящийся в вашем публичном каталоге, используйте следующий тег скрипта –

<script src = "/static/main.js" />

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

ExpressJS – данные формы

Формы являются неотъемлемой частью Интернета. Почти каждый веб-сайт, который мы посещаем, предлагает нам формы, которые отправляют или получают некоторую информацию для нас. Чтобы начать работу с формами, мы сначала установим body-parser (для анализа JSON и URL-кодированных данных) и multer (для анализа multipart / form data) промежуточное программное обеспечение.

Чтобы установить body-parser и multer , перейдите в свой терминал и используйте –

npm install --save body-parser multer

Замените содержимое файла index.js следующим кодом –

var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();
var app = express();

app.get('/', function(req, res){
   res.render('form');
});

app.set('view engine', 'pug');
app.set('views', './views');

// for parsing application/json
app.use(bodyParser.json()); 

// for parsing application/xwww-
app.use(bodyParser.urlencoded({ extended: true })); 
//form-urlencoded

// for parsing multipart/form-data
app.use(upload.array()); 
app.use(express.static('public'));

app.post('/', function(req, res){
   console.log(req.body);
   res.send("recieved your request!");
});
app.listen(3000);

После импорта анализатора тела и multer мы будем использовать body-parser для синтаксического анализа запросов заголовков json и x-www-form-urlencoded, в то время как мы будем использовать multer для анализа multipart / form-data.

Давайте создадим HTML-форму, чтобы проверить это. Создайте новый вид с именем form.pug со следующим кодом –

html
html
   head
      title Form Tester
   body
      form(action = "/", method = "POST")
         div
            label(for = "say") Say:
            input(name = "say" value = "Hi")
         br
         div
            label(for = "to") To:
            input(name = "to" value = "Express forms")
         br
         button(type = "submit") Send my greetings

Запустите ваш сервер, используя следующее.

nodemon index.js

Теперь перейдите на localhost: 3000 / и заполните форму, как вам нравится, и отправьте ее. Следующий ответ будет отображаться –

Ответ на отправку формы

Посмотрите на вашу консоль; он покажет тело вашего запроса в виде объекта JavaScript, как на следующем снимке экрана –

Консольный вывод для формы

Объект req.body содержит ваше проанализированное тело запроса. Чтобы использовать поля из этого объекта, просто используйте их как обычные объекты JS.

Это наиболее рекомендуемый способ отправки запроса. Есть много других способов, но они не имеют отношения к этому, потому что наше приложение Express будет обрабатывать все эти запросы одинаково. Чтобы узнать больше о различных способах подачи запроса, загляните на эту страницу.

ExpressJS – База данных

Мы продолжаем получать запросы, но в итоге нигде не храним их. Нам нужна база данных для хранения данных. Для этого мы будем использовать базу данных NoSQL под названием MongoDB .

Чтобы установить и прочитать о Mongo, перейдите по этой ссылке.

Чтобы использовать Mongo с Express, нам нужен клиентский API для узла. У нас есть несколько вариантов, но в этом уроке мы остановимся на мангусте . Mongoose используется для моделирования документов в Node для MongoDB. Для моделирования документов мы создаем модель (очень похожую на класс в документно-ориентированном программировании), а затем мы создаем документы, используя эту модель (как мы создаем документы класса в ООП). Вся наша обработка будет производиться на этих «документах», затем, наконец, мы запишем эти документы в нашу базу данных.

Настройка мангуста

Теперь, когда вы установили Mongo, давайте установим Mongoose точно так же, как мы устанавливали другие наши пакеты узлов –

npm install --save mongoose

Прежде чем мы начнем использовать mongoose, мы должны создать базу данных, используя оболочку Mongo. Чтобы создать новую базу данных, откройте свой терминал и введите «Монго». Запустится оболочка Mongo, введите следующий код –

use my_db

Новая база данных будет создана для вас. Всякий раз, когда вы открываете оболочку mongo, она по умолчанию будет «тестировать» БД, и вам придется перейти в базу данных, используя ту же команду, что и выше.

Чтобы использовать Mongoose, нам потребуется это в нашем файле index.js, а затем подключиться к сервису mongodb, работающему на mongodb: // localhost .

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

Теперь наше приложение подключено к нашей базе данных, давайте создадим новую модель. Эта модель будет выступать в качестве коллекции в нашей базе данных. Чтобы создать новую модель, используйте следующий код перед определением любого маршрута –

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});
var Person = mongoose.model("Person", personSchema);

Приведенный выше код определяет схему для человека и используется для создания человека в режиме Mongoose.

Сохранение документов

Теперь мы создадим новую HTML-форму; эта форма поможет вам получить информацию о человеке и сохранить его в нашей базе данных. Чтобы создать форму, создайте новый файл представления с именем person.pug в каталоге представлений следующего содержания:

html
head
   title Person
   body
      form(action = "/person", method = "POST")
      div
         label(for = "name") Name: 
         input(name = "name")
      br
      div
         label(for = "age") Age: 
         input(name = "age")
      br
      div
         label(for = "nationality") Nationality: 
         input(name = "nationality")
      br
      button(type = "submit") Create new person

Также добавьте новый маршрут get в index.js для рендеринга этого документа –

app.get('/person', function(req, res){
   res.render('person');
});

Перейдите к « localhost: 3000 / person », чтобы проверить правильность вывода формы. Обратите внимание, что это просто пользовательский интерфейс, он еще не работает. На следующем снимке экрана показано, как отображается форма.

Мангуст Создать

Теперь мы определим обработчик почтового маршрута в / person, который будет обрабатывать этот запрос

app.post('/person', function(req, res){
   var personInfo = req.body; //Get the parsed information
   
   if(!personInfo.name || !personInfo.age || !personInfo.nationality){
      res.render('show_message', {
         message: "Sorry, you provided worng info", type: "error"});
   } else {
      var newPerson = new Person({
         name: personInfo.name,
         age: personInfo.age,
         nationality: personInfo.nationality
      });
		
      newPerson.save(function(err, Person){
         if(err)
            res.render('show_message', {message: "Database error", type: "error"});
         else
            res.render('show_message', {
               message: "New person added", type: "success", person: personInfo});
      });
   }
});

В приведенном выше коде, если мы получим любое пустое поле или не получим никакого поля, мы отправим ответ об ошибке. Но если мы получим правильно сформированный документ, мы создадим документ newPerson из модели Person и сохраним его в нашей БД с помощью функции newPerson.save () . Это определено в Mongoose и принимает обратный вызов в качестве аргумента. Этот обратный вызов имеет 2 аргумента – ошибка и ответ. Эти аргументы будут отображать представление show_message .

Чтобы показать ответ от этого маршрута, нам также нужно создать представление show_message . Создайте новый вид с помощью следующего кода –

html
   head
      title Person
   body
      if(type == "error")
         h3(style = "color:red") #{message}
      else
         h3 New person, 
            name: #{person.name}, 
            age: #{person.age} and 
            nationality: #{person.nationality} added!

При успешной отправке формы мы получим следующий ответ (show_message.pug)

Мангуста Ответ

Теперь у нас есть интерфейс для создания людей .

Получение документов

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

Model.find (условия, обратный вызов)

Эта функция находит все документы, соответствующие полям в объекте условий. Те же операторы, которые используются в Mongo, также работают в mongoose. Например,

Person.find(function(err, response){
   console.log(response);
});

Это позволит получить все документы из коллекции человека.

Person.find({name: "Ayush", age: 20}, 
   function(err, response){
      console.log(response);
});

При этом будут получены все документы, для которых поле имеет имя «Аюш» и возраст 20 лет.

Мы также можем предоставить необходимую проекцию, то есть поля, которые нам нужны. Например, если нам нужны только имена людей, национальность которых “индиец” , мы используем –

Person.find({nationality: "Indian"}, "name", function(err, response){
   console.log(response);
});

Model.findOne (условия, обратный вызов)

Эта функция всегда выбирает один, самый важный документ. Он имеет те же точные аргументы, что и Model.find () .

Model.findById (id, обратный вызов)

Эта функция принимает _id (определенный mongo) в качестве первого аргумента, необязательную строку проекции и обратный вызов для обработки ответа. Например,

Person.findById("507f1f77bcf86cd799439011", function(err, response){
   console.log(response);
});

Давайте теперь создадим маршрут для просмотра всех записей людей –

var express = require('express');
var app = express();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.get('/people', function(req, res){
   Person.find(function(err, response){
      res.json(response);
   });
});

app.listen(3000);

Обновление документов

Mongoose предоставляет 3 функции для обновления документов. Функции описаны ниже –

Model.update (состояние, обновления, обратный вызов)

Эта функция принимает условия и обновляет объект в качестве входных данных и применяет изменения ко всем документам, соответствующим условиям в коллекции. Например, следующий код обновит национальность «американец» во всех документах Person –

Person.update({age: 25}, {nationality: "American"}, function(err, response){
   console.log(response);
});

Model.findOneAndUpdate (условие, обновления, обратный вызов)

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

Person.findOneAndUpdate({name: "Ayush"}, {age: 40}, function(err, response) {
   console.log(response);
});

Model.findByIdAndUpdate (идентификатор, обновления, обратный вызов)

Эта функция обновляет один документ, идентифицируемый по его идентификатору. Например,

Person.findByIdAndUpdate("507f1f77bcf86cd799439011", {name: "James"}, 
   function(err, response){
      console.log(response);
});

Давайте теперь создадим маршрут для обновления людей. Это будет маршрут PUT с идентификатором в качестве параметра и деталями в полезной нагрузке.

var express = require('express');
var app = express();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.put('/people/:id', function(req, res){
   Person.findByIdAndUpdate(req.params.id, req.body, function(err, response){
      if(err) res.json({message: "Error in updating person with id " + req.params.id});
      res.json(response);
   });
});

app.listen(3000);

Чтобы проверить этот маршрут, введите в своем терминале следующее (замените идентификатор на идентификатор из созданных вами людей ) –

curl -X PUT --data "name = James&age = 20&nationality = American
"http://localhost:3000/people/507f1f77bcf86cd799439011

Это обновит документ, связанный с идентификатором, указанным в маршруте, с указанными выше деталями.

Удаление документов

Мы рассмотрели создание, чтение и обновление , теперь мы увидим, как Mongoose можно использовать для удаления документов. У нас есть 3 функции здесь, точно так же, как обновление.

Model.remove (условие, [обратный вызов])

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

Person.remove({age:20});

Model.findOneAndRemove (условие, [обратный вызов])

Эта функция удаляет один , наиболее релевантный документ в соответствии с объектом условий. Давайте выполним следующий код, чтобы понять то же самое.

Person.findOneAndRemove({name: "Ayush"});

Model.findByIdAndRemove (id, [callback])

Эта функция удаляет один документ, идентифицируемый по его идентификатору. Например,

Person.findByIdAndRemove("507f1f77bcf86cd799439011");

Давайте теперь создадим маршрут для удаления людей из нашей базы данных.

var express = require('express');
var app = express();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.delete('/people/:id', function(req, res){
   Person.findByIdAndRemove(req.params.id, function(err, response){
      if(err) res.json({message: "Error in deleting record id " + req.params.id});
      else res.json({message: "Person with id " + req.params.id + " removed."});
   });
});

app.listen(3000);

Чтобы проверить вывод, используйте следующую команду curl –

curl -X DELETE http://localhost:3000/people/507f1f77bcf86cd799439011

Это удалит человека с указанным идентификатором, выдающего следующее сообщение –

{message: "Person with id 507f1f77bcf86cd799439011 removed."}

Это завершает, как мы можем создавать простые приложения CRUD, используя MongoDB, Mongoose и Express. Чтобы узнать больше о Mongoose, прочитайте документацию по API.

ExpressJS – Cookies

Файлы cookie – это простые небольшие файлы / данные, которые отправляются клиенту по запросу сервера и хранятся на стороне клиента. Каждый раз, когда пользователь загружает сайт обратно, этот файл cookie отправляется вместе с запросом. Это помогает нам отслеживать действия пользователя.

Ниже приведены многочисленные примеры использования файлов cookie HTTP.

  • Управление сессиями
  • Персонализация (системы рекомендаций)
  • Отслеживание пользователей

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

npm install --save cookie-parser

Теперь, чтобы использовать куки с Express, нам потребуется cookie-парсер . cookie-parser – это промежуточное ПО, которое анализирует куки-файлы, прикрепленные к объекту запроса клиента . Чтобы использовать его, нам потребуется это в нашем файле index.js ; это можно использовать так же, как мы используем другое промежуточное программное обеспечение. Здесь мы будем использовать следующий код.

var cookieParser = require('cookie-parser');
app.use(cookieParser());

cookie-анализатор анализирует заголовок Cookie и заполняет req.cookies объектом, обозначенным именами cookie. Чтобы установить новый файл cookie, давайте определим новый маршрут в вашем приложении Express, например:

var express = require('express');
var app = express();

app.get('/', function(req, res){
   res.cookie('name', 'express').send('cookie set'); //Sets name = express
});

app.listen(3000);

Чтобы проверить, установлен ваш cookie или нет, просто зайдите в браузер, запустите консоль и введите –

console.log(document.cookie);

Вы получите вывод, как (у вас может быть больше куки, возможно, из-за расширений в вашем браузере) –

"name = express"

Браузер также отправляет файлы cookie каждый раз, когда запрашивает сервер. Чтобы просмотреть файлы cookie с вашего сервера, на консоли сервера в маршруте добавьте следующий код к этому маршруту.

console.log('Cookies: ', req.cookies);

В следующий раз, когда вы отправите запрос по этому маршруту, вы получите следующий вывод.

Cookies: { name: 'express' }

Добавление файлов cookie со сроком действия

Вы можете добавить куки, срок действия которых истекает. Чтобы добавить cookie, срок действия которого истекает, просто передайте объект со свойством expire, установленным на время, когда вы хотите, чтобы срок его действия истек. Например,

//Expires after 360000 ms from the time it is set.
res.cookie(name, 'value', {expire: 360000 + Date.now()}); 

Другой способ установить время истечения – использовать свойство maxAge . Используя это свойство, мы можем указать относительное время вместо абсолютного. Ниже приведен пример этого метода.

//This cookie also expires after 360000 ms from the time it is set.
res.cookie(name, 'value', {maxAge: 360000});

Удаление существующих файлов cookie

Чтобы удалить cookie, используйте функцию clearCookie. Например, если вам нужно очистить файл cookie с именем foo , используйте следующий код.

var express = require('express');
var app = express();

app.get('/clear_cookie_foo', function(req, res){
   res.clearCookie('foo');
   res.send('cookie foo cleared');
});

app.listen(3000);

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

ExpressJS – Сессии

HTTP не имеет состояния; Чтобы связать запрос с любым другим запросом, вам нужен способ хранения пользовательских данных между HTTP-запросами. Файлы cookie и параметры URL являются подходящими способами передачи данных между клиентом и сервером. Но они оба читабельны и на стороне клиента. Сессии решают именно эту проблему. Вы назначаете клиенту идентификатор, и он делает все дальнейшие запросы, используя этот идентификатор. Информация, связанная с клиентом, хранится на сервере, связанном с этим идентификатором.

Нам понадобится Express-сессия , поэтому установите его, используя следующий код.

npm install --save express-session

Мы установим промежуточное программное обеспечение для сессии и cookie-парсера . В этом примере мы будем использовать хранилище по умолчанию для хранения сессий, то есть MemoryStore. Никогда не используйте это в производственных условиях. Промежуточное программное обеспечение сеанса обрабатывает все для нас, т.е. создает сеанс, устанавливает cookie сеанса и создает объект сеанса в объекте req .

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

var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('express-session');

var app = express();

app.use(cookieParser());
app.use(session({secret: "Shh, its a secret!"}));

app.get('/', function(req, res){
   if(req.session.page_views){
      req.session.page_views++;
      res.send("You visited this page " + req.session.page_views + " times");
   } else {
      req.session.page_views = 1;
      res.send("Welcome to this page for the first time!");
   }
});
app.listen(3000);

Код выше, когда пользователь посещает сайт, создает новый сеанс для пользователя и назначает ему cookie. В следующий раз, когда пользователь приходит, cookie проверяется, и переменная сеанса page_view обновляется соответственно.

Теперь, если вы запустите приложение и перейдете на localhost: 3000 , будет отображен следующий вывод.

Первый визит

Если вы вернетесь на страницу, счетчик страниц увеличится. Страница на следующем скриншоте обновлялась 42 раза.

Первый визит

ExpressJS – Аутентификация

Аутентификация – это процесс, в котором предоставленные учетные данные сравниваются с данными в файле в базе данных авторизованных пользователей в локальной операционной системе или на сервере аутентификации. Если учетные данные совпадают, процесс завершается, и пользователю предоставляется авторизация для доступа.

Чтобы создать систему аутентификации, нам нужно создать страницу регистрации и хранилище паролей пользователей. Следующий код создает для нас учетную запись и сохраняет ее в памяти. Это только для демонстрации; рекомендуется, чтобы постоянное хранилище (база данных или файлы) всегда использовалось для хранения пользовательской информации.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer(); 
var session = require('express-session');
var cookieParser = require('cookie-parser');

app.set('view engine', 'pug');
app.set('views','./views');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true })); 
app.use(upload.array());
app.use(cookieParser());
app.use(session({secret: "Your secret key"}));

var Users = [];

app.get('/signup', function(req, res){
   res.render('signup');
});

app.post('/signup', function(req, res){
   if(!req.body.id || !req.body.password){
      res.status("400");
      res.send("Invalid details!");
   } else {
      Users.filter(function(user){
         if(user.id === req.body.id){
            res.render('signup', {
               message: "User Already Exists! Login or choose another user id"});
         }
      });
      var newUser = {id: req.body.id, password: req.body.password};
      Users.push(newUser);
      req.session.user = newUser;
      res.redirect('/protected_page');
   }
});

app.listen(3000);

Теперь для формы регистрации создайте новое представление с именем signup.jade.

SIGNUP.JADE

html
   head
      title Signup
   body
      if(message)
         h4 #{message}
         form(action = "/signup" method = "POST")
         input(name = "id" type = "text" required placeholder = "User ID")
         input(name = "password" type = "password" required placeholder = "Password")
         button(type = "Submit") Sign me up!

Проверьте, загружается ли эта страница, посетив localhost: 3000 / регистрация.

Форма регистрации

Мы установили обязательный атрибут для обоих полей, поэтому браузеры с поддержкой HTML5 не позволят нам отправить эту форму, пока мы не предоставим и идентификатор, и пароль. Если кто-то попытается зарегистрироваться, используя запрос скручивания без идентификатора пользователя или пароля, появится сообщение об ошибке. Создайте новый файл с именем protected_page.pug в представлениях со следующим содержанием –

html
   head
      title Protected page
   body
      div Hey #{id}, How are you doing today?
      div Want to log out?
      div Logout

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

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer(); 
var session = require('express-session');
var cookieParser = require('cookie-parser');

app.set('view engine', 'pug');
app.set('views','./views');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true })); 
app.use(upload.array());
app.use(cookieParser());
app.use(session({secret: "Your secret key"}));

var Users = [];

app.get('/signup', function(req, res){
   res.render('signup');
});

app.post('/signup', function(req, res){
   if(!req.body.id || !req.body.password){
      res.status("400");
      res.send("Invalid details!");
   } else {
      Users.filter(function(user){
         if(user.id === req.body.id){
            res.render('signup', {
               message: "User Already Exists! Login or choose another user id"});
         }
      });
      var newUser = {id: req.body.id, password: req.body.password};
      Users.push(newUser);
      req.session.user = newUser;
      res.redirect('/protected_page');
   }
});
function checkSignIn(req, res){
   if(req.session.user){
      next();     //If session exists, proceed to page
   } else {
      var err = new Error("Not logged in!");
      console.log(req.session.user);
      next(err);  //Error, trying to access unauthorized page!
   }
}
app.get('/protected_page', checkSignIn, function(req, res){
   res.render('protected_page', {id: req.session.user.id})
});

app.get('/login', function(req, res){
   res.render('login');
});

app.post('/login', function(req, res){
   console.log(Users);
   if(!req.body.id || !req.body.password){
      res.render('login', {message: "Please enter both id and password"});
   } else {
      Users.filter(function(user){
         if(user.id === req.body.id && user.password === req.body.password){
            req.session.user = user;
            res.redirect('/protected_page');
         }
      });
      res.render('login', {message: "Invalid credentials!"});
   }
});

app.get('/logout', function(req, res){
   req.session.destroy(function(){
      console.log("user logged out.")
   });
   res.redirect('/login');
});

app.use('/protected_page', function(err, req, res, next){
console.log(err);
   //User should be authenticated! Redirect him to log in.
   res.redirect('/login');
});

app.listen(3000);

Мы создали функцию промежуточного программного обеспечения checkSignIn, чтобы проверить, вошел ли пользователь в систему. Защищенная_страница использует эту функцию. Чтобы выйти из системы, мы уничтожаем сессию.

Давайте теперь создадим страницу входа. Назовите представление как login.pug и введите содержимое –

html
   head
      title Signup
   body
      if(message)
         h4 #{message}
         form(action = "/login" method = "POST")
         input(name = "id" type = "text" required placeholder = "User ID")
         input(name = "password" type = "password" required placeholder = "Password")
         button(type = "Submit") Log in

Наше простое приложение для аутентификации завершено; давайте теперь протестируем приложение. Запустите приложение, используя nodemon index.js , и перейдите к localhost: 3000 / signup.

Введите имя пользователя и пароль и нажмите «Зарегистрироваться». Вы будете перенаправлены на страницу protected_page, если данные верны / уникальны –

Защищенная страница

Теперь выйдите из приложения. Это перенаправит нас на страницу входа –

Авторизоваться

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

ExpressJS – RESTFul API

API всегда необходим для создания мобильных приложений, одностраничных приложений, использования вызовов AJAX и предоставления данных клиентам. Популярный архитектурный стиль структурирования и именования этих API-интерфейсов и конечных точек называется REST (репрезентативное состояние передачи) . HTTP 1.1 был разработан с учетом принципов REST. REST был представлен Роем ​​Филдингом в 2000 году в его «Бумажной диссертации».

RESTful URI и методы предоставляют нам практически всю информацию, необходимую для обработки запроса. Таблица, приведенная ниже, суммирует, как должны использоваться различные глаголы и как должны называться URI. Мы будем создавать API фильмов к концу; давайте теперь обсудим, как это будет структурировано.

метод URI подробности функция
ПОЛУЧИТЬ /фильмы Безопасный, кэшируемый Получает список всех фильмов и их детали
ПОЛУЧИТЬ / Фильмы / 1234 Безопасный, кэшируемый Получает подробную информацию о фильме id 1234
СООБЩЕНИЕ /фильмы N / A Создает новый фильм с предоставленной информацией. Ответ содержит URI для этого вновь созданного ресурса.
ПОЛОЖИЛ / Фильмы / 1234 идемпотент Изменяет идентификатор фильма 1234 (создает его, если он еще не существует). Ответ содержит URI для этого вновь созданного ресурса.
УДАЛЯТЬ / Фильмы / 1234 идемпотент Идентификатор фильма 1234 следует удалить, если он существует. Ответ должен содержать статус запроса.
УДАЛИТЬ или ПОСТАВИТЬ /фильмы Недействительным Должен быть недействительным. DELETE и PUT должны указывать, над каким ресурсом они работают.

Давайте теперь создадим этот API в Express. Мы будем использовать JSON в качестве нашего транспортного формата данных, так как с ним легко работать в JavaScript и есть другие преимущества. Замените файл index.js на файл movies.js, как показано в следующей программе.

index.js

var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();

var app = express();

app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.array());

//Require the Router we defined in movies.js
var movies = require('./movies.js');

//Use the Router on the sub route /movies
app.use('/movies', movies);

app.listen(3000);

Теперь, когда мы настроили наше приложение, давайте сосредоточимся на создании API.

Начните с настройки файла movies.js. Мы не используем базу данных для хранения фильмов, а храним их в памяти; поэтому каждый раз, когда сервер перезагружается, добавленные нами фильмы исчезают. Это можно легко имитировать с помощью базы данных или файла (с помощью модуля node fs).

После того, как вы импортируете Express, создайте маршрутизатор и экспортируйте его, используя module.exports

var express = require('express');
var router = express.Router();
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];

//Routes will go here
module.exports = router;

ПОЛУЧИТЬ маршруты

Давайте определим маршрут GET для получения всех фильмов –

router.get('/', function(req, res){
   res.json(movies);
});

Чтобы проверить, работает ли это нормально, запустите ваше приложение, затем откройте терминал и введите –

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET 
localhost:3000/movies

Следующий ответ будет отображаться –

[{"id":101,"name":"Fight Club","year":1999,"rating":8.1},
{"id":102,"name":"Inception","year":2010,"rating":8.7},
{"id":103,"name":"The Dark Knight","year":2008,"rating":9},
{"id":104,"name":"12 Angry Men","year":1957,"rating":8.9}]

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

router.get('/:id([0-9]{3,})', function(req, res){
   var currMovie = movies.filter(function(movie){
      if(movie.id == req.params.id){
         return true;
      }
   });
   if(currMovie.length == 1){
      res.json(currMovie[0])
   } else {
      res.status(404);//Set status to 404 as movie was not found
      res.json({message: "Not Found"});
   }
});

Это даст нам фильмы в соответствии с идентификатором, который мы предоставили. Чтобы проверить вывод, используйте следующую команду в вашем терминале –

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET 
localhost:3000/movies/101

Вы получите следующий ответ –

{"id":101,"name":"Fight Club","year":1999,"rating":8.1}

Если вы посещаете неверный маршрут, он выдаст ошибку not GET, а если вы посетите действующий маршрут с идентификатором, который не существует, он выдаст ошибку 404.

Мы закончили с маршрутами GET, теперь давайте перейдем к маршруту POST .

POST маршрут

Используйте следующий маршрут для обработки POST- данных –

router.post('/', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9].[0-9]$/g)){
      
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      var newId = movies[movies.length-1].id+1;
      movies.push({
         id: newId,
         name: req.body.name,
         year: req.body.year,
         rating: req.body.rating
      });
      res.json({message: "New movie created.", location: "/movies/" + newId});
   }
});

Это создаст новый фильм и сохранит его в переменной movies. Чтобы проверить этот маршрут, введите следующий код в своем терминале –

curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" http://localhost:3000/movies

Следующий ответ будет отображаться –

{"message":"New movie created.","location":"/movies/105"}

Чтобы проверить, было ли это добавлено к объекту movies, снова запустите запрос get для / movies / 105 . Следующий ответ будет отображаться –

{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}

Давайте перейдем к созданию маршрутов PUT и DELETE.

PUT маршрут

Маршрут PUT почти совпадает с маршрутом POST. Мы будем указывать идентификатор для объекта, который будет обновлен / создан. Создайте маршрут следующим образом.

router.put('/:id', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9].[0-9]$/g) ||
      !req.params.id.toString().match(/^[0-9]{3,}$/g)){
      
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(req.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         });
         res.json({message: "New movie created.", location: "/movies/" + req.params.id});
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         };
         res.json({message: "Movie id " + req.params.id + " updated.", 
            location: "/movies/" + req.params.id});
      }
   }
});

Этот маршрут будет выполнять функцию, указанную в таблице выше. Он обновит объект новыми деталями, если он существует. Если он не существует, он создаст новый объект. Чтобы проверить маршрут, используйте следующую команду curl. Это обновит существующий фильм. Чтобы создать новый фильм, просто измените идентификатор на несуществующий идентификатор.

curl -X PUT --data "name = Toy%20story&year = 1995&rating = 8.5" 
http://localhost:3000/movies/101

отклик

{"message":"Movie id 101 updated.","location":"/movies/101"}

УДАЛИТЬ маршрут

Используйте следующий код для создания маршрута удаления.

router.delete('/:id', function(req, res){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(req.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      res.json({message: "Not found"});
   } else {
      movies.splice(removeIndex, 1);
      res.send({message: "Movie id " + req.params.id + " removed."});
   }
});

Проверьте маршрут так же, как мы проверяли другие маршруты. При успешном удалении (например, с идентификатором 105) вы получите следующий вывод:

{message: "Movie id 105 removed."}

Наконец, наш файл movies.js будет выглядеть следующим образом.

var express = require('express');
var router = express.Router();
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];
router.get('/:id([0-9]{3,})', function(req, res){
   var currMovie = movies.filter(function(movie){
      if(movie.id == req.params.id){
         return true;
      }
   });
   
   if(currMovie.length == 1){
      res.json(currMovie[0])
   } else {
      res.status(404);  //Set status to 404 as movie was not found
      res.json({message: "Not Found"});
   }
});
router.post('/', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9].[0-9]$/g)){
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      var newId = movies[movies.length-1].id+1;
      movies.push({
         id: newId,
         name: req.body.name,
         year: req.body.year,
         rating: req.body.rating
      });
      res.json({message: "New movie created.", location: "/movies/" + newId});
   }
});

router.put('/:id', function(req, res) {
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9].[0-9]$/g) ||
      !req.params.id.toString().match(/^[0-9]{3,}$/g)){
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(req.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         });
         res.json({
            message: "New movie created.", location: "/movies/" + req.params.id});
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         };
         res.json({message: "Movie id " + req.params.id + " updated.",
            location: "/movies/" + req.params.id});
      }
   }
});

router.delete('/:id', function(req, res){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(req.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      res.json({message: "Not found"});
   } else {
      movies.splice(removeIndex, 1);
      res.send({message: "Movie id " + req.params.id + " removed."});
   }
});
module.exports = router;

Это завершает наш REST API. Теперь вы можете создавать гораздо более сложные приложения, используя этот простой архитектурный стиль и Express.

ExpressJS – Строительные леса

Скаффолдинг позволяет нам легко создавать каркас для веб-приложения . Мы вручную создаем наш публичный каталог, добавляем промежуточное программное обеспечение, создаем отдельные файлы маршрутов и т. Д. Инструмент скаффолдинга настраивает все эти вещи для нас, чтобы мы могли непосредственно приступить к созданию нашего приложения.

Подмости, которые мы будем использовать, называются Yeoman . Это инструмент для скаффолдинга, созданный для Node.js, но также имеющий генераторы для нескольких других фреймворков (таких как flask, rails, django и т. Д.). Чтобы установить Yeoman, введите следующую команду в своем терминале –

npm install -g yeoman

Yeoman использует генераторы для создания приложений. Чтобы проверить генераторы, доступные на npm для использования с Yeoman, вы можете нажать на эту ссылку . В этом уроке мы будем использовать «генератор-экспресс-простой» . Чтобы установить этот генератор, введите следующую команду в своем терминале –

npm install -g generator-express-simple

Чтобы использовать этот генератор, введите следующую команду –

yo express-simple test-app

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

express-simple comes with bootstrap and jquery
[?] Select the express version you want: 4.x
[?] Do you want an mvc express app: Yes
[?] Select the css preprocessor you would like to use: sass
[?] Select view engine you would like to use: jade
[?] Select the build tool you want to use for this project: gulp
[?] Select the build tool you want to use for this project: gulp
[?] Select the language you want to use for the build tool: javascript
   create public/sass/styles.scss
   create public/js/main.js
   create views/layout.jade
   create views/index.jade
   create views/404.jade
   create app.js
   create config.js
   create routes/index.js
   create package.json
   create bower.json
identical .bowerrc
identical .editorconfig
identical .gitignore
identical .jshintrc
   create gulpfile.js

I'm all done. Running bower install & npm install for you to install the
required dependencies. If this fails, try running the command yourself.

Затем он создаст новое приложение для вас, установит все зависимости, добавит несколько страниц в ваше приложение (домашняя страница, страница 404 не найдена и т. Д.) И предоставит вам структуру каталогов для работы.

Этот генератор создает для нас очень простую структуру. Изучите множество генераторов, доступных для Express, и выберите тот, который вам подходит. Шаги для работы со всеми генераторами одинаковы. Вам нужно будет установить генератор, запустить его с помощью Yeoman; он задаст вам несколько вопросов, а затем создаст каркас для вашего приложения на основе ваших ответов.

ExpressJS – Обработка ошибок

Обработка ошибок в Express выполняется с использованием промежуточного программного обеспечения. Но это промежуточное ПО обладает особыми свойствами. Промежуточное программное обеспечение для обработки ошибок определяется так же, как и другие функции промежуточного программного обеспечения, за исключением того, что функции обработки ошибок ДОЛЖНЫ иметь четыре аргумента вместо трех – err, req, res, next . Например, чтобы отправить ответ на любую ошибку, мы можем использовать –

app.use(function(err, req, res, next) {
   console.error(err.stack);
   res.status(500).send('Something broke!');
});

До сих пор мы обрабатывали ошибки в самих маршрутах. Промежуточное программное обеспечение для обработки ошибок позволяет нам отделить нашу логику ошибок и соответственно отправлять ответы. Метод next (), который мы обсуждали в промежуточном ПО, приводит нас к следующему обработчику промежуточного ПО / маршрута .

Для обработки ошибок у нас есть следующая (err) функция. Вызов этой функции пропускает все промежуточное программное обеспечение и сопоставляет нас со следующим обработчиком ошибок для этого маршрута. Позвольте нам понять это на примере.

var express = require('express');
var app = express();

app.get('/', function(req, res){
   //Create an error and pass it to the next function
   var err = new Error("Something went wrong");
   next(err);
});

/*
 * other route handlers and middleware here
 * ....
 */

//An error handling middleware
app.use(function(err, req, res, next) {
   res.status(500);
   res.send("Oops, something went wrong.")
});

app.listen(3000);

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

Обработка ошибок

ExpressJS – отладка

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

Чтобы увидеть все внутренние журналы, используемые в Express, установите для переменной среды DEBUG значение Express: * при запуске приложения –

DEBUG = express:* node index.js

Будет отображен следующий вывод.

Журнал отладки

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

DEBUG = express:application,express:router node index.js

Отладка отключена по умолчанию и автоматически включается в производственной среде. Отладка также может быть расширена в соответствии с вашими потребностями, вы можете прочитать больше об этом на странице npm.

ExpressJS – лучшие практики

В отличие от Django и Rails, у которых есть определенный способ работы, структура файла и т. Д., Express не следует определенному пути. Это означает, что вы можете структурировать приложение так, как вам нравится. Но по мере увеличения размера вашего приложения его очень сложно поддерживать, если оно не имеет четко определенной структуры. В этой главе мы рассмотрим обычно используемые структуры каталогов и разделение задач при создании наших приложений.

Сначала мы обсудим лучшие практики создания приложений для узлов и Express.

  • Всегда начинайте проект узла, используя npm init .

  • Всегда устанавливайте зависимости с помощью –save или –save-dev . Это гарантирует, что если вы перейдете на другую платформу, вы можете просто запустить npm install для установки всех зависимостей.

  • Придерживайтесь строчных имен файлов и переменных camelCase. Если вы посмотрите на любой модуль npm, он назван в нижнем регистре и разделен черточками. Всякий раз, когда вам нужны эти модули, используйте camelCase.

  • Не добавляйте node_modules в свои репозитории. Вместо этого npm устанавливает все на машины для разработки.

  • Используйте файл конфигурации для хранения переменных

  • Группируйте и изолируйте маршруты в своем собственном файле. Например, возьмем операции CRUD в примере фильмов, которые мы видели на странице API REST.

Всегда начинайте проект узла, используя npm init .

Всегда устанавливайте зависимости с помощью –save или –save-dev . Это гарантирует, что если вы перейдете на другую платформу, вы можете просто запустить npm install для установки всех зависимостей.

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

Не добавляйте node_modules в свои репозитории. Вместо этого npm устанавливает все на машины для разработки.

Используйте файл конфигурации для хранения переменных

Группируйте и изолируйте маршруты в своем собственном файле. Например, возьмем операции CRUD в примере фильмов, которые мы видели на странице API REST.

Структура каталогов

Давайте теперь обсудим Экспресс-структуру каталогов.

Веб-сайты

Express не имеет определенной сообществом структуры для создания приложений. Ниже приводится основная структура проекта для веб-сайта.

test-project/
   node_modules/
   config/
      db.js                //Database connection and configuration
      credentials.js       //Passwords/API keys for external services used by your app
      config.js            //Other environment variables
   models/                 //For mongoose schemas
      users.js
      things.js
   routes/                 //All routes for different entities in different files 
      users.js
      things.js
   views/
      index.pug
      404.pug
        ...
   public/                 //All static content being served
      images/
      css/
      javascript/
   app.js
   routes.js               //Require all routes in this and then require this file in 
   app.js 
   package.json

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

https://code.tutsplus.com/tutorials/build-a-complete-mvc-website-with-expressjs–net-34168

а также,

https://www.terlici.com/2014/08/25/best-practices-express-structure.html .

RESTful API

API проще в разработке; им не нужен общедоступный каталог или каталог представлений. Используйте следующую структуру для создания API –

test-project/
   node_modules/
   config/
      db.js                //Database connection and configuration
      credentials.js       //Passwords/API keys for external services used by your app
   models/                 //For mongoose schemas
      users.js
      things.js
   routes/                 //All routes for different entities in different files 
      users.js
      things.js
   app.js
   routes.js               //Require all routes in this and then require this file in 
   app.js 
   package.json

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

ExpressJS – Ресурсы

В этой главе перечислены различные ресурсы, которые мы использовали для этого урока.

Самая важная ссылка – это, конечно, документы Express API – https://expressjs.com/en/4x/api.html.

Руководства, представленные на сайте Express по различным аспектам, также весьма полезны –

маршрутизация

Промежуточное

Обработка ошибок

отладка

Список полезных книг и блогов по Express доступен по адресу https://expressjs.com/en/resources/books-blogs.html.

Список наиболее часто используемого промежуточного программного обеспечения с Express доступен по адресу https://expressjs.com/en/resources/middleware.html.

Эти блоги с советами и советами по Express могут оказаться полезными –

https://derickbailey.com/categories/tips-and-tricks/

https://scotch.io/tutorials/learn-to-use-the-new-router-in+-expressjs-4

Структура приложения – https://www.terlici.com/2014/08/25/best-practices-express-structure.html

RESTful APIs –

https://www.thepolyglotdeveloper.com/2015/10/create-a-simple-restful-api-with-node-js/

https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

https://devcenter.heroku.com/articles/mean-apps-restful-api

https://pixelhandler.com/posts/develop-a-restful-api-using-nodejs-with-express-and-mongoose

http://cwbuecheler.com/web/tutorials/2014/restful-web-app-node-express-mongodb/

Для расширенной аутентификации используйте PassportJS – http://passportjs.org

Express: веб-фреймворк для Node.js. Руководство пользователя

Express: вебфреймворк для Node.js. Руководство пользователя

var app = express.createServer();
app.get('/', function(req, res) {
    res.send('Hello World');
});
app.listen(3000);

Возможности

  • Понятная маршрутизация
  • Помощники перенаправления (redirect helpers)
  • Динамические помощники представлений
  • Опции представлений уровня приложения
  • Взаимодействие с контентом
  • Монтирование приложений
  • Ориентированность на высокую производительность
  • Рендеринг шаблонов и поддержка фрагментных шаблонов (view partials)
  • Конфигурации, быстро переключаемые под разные задачи (development, production, и т.д.)
  • Хранимые в сессии всплывающие сообщения (flash messages)
  • Сделано на основе Connect
  • Скрипт express для быстрой генерации каркаса приложения
  • Высокое покрытие тестами

Установка

npm install express

или, чтобы иметь доступ к команде express, установите глобально:

npm install -g express

Быстрый старт

Проще всего начать работу с Express можно выполнив команду express, которая сгенерирует приложение:

Создание приложения:

npm install -g express
express /tmp/foo && cd /tmp/foo

Установка зависимостей:

npm install -d

Запуск сервера:

node app.js

Создание сервера

Чтобы создать экземпляр express.HTTPServer, просто вызовите метод createServer(). С помощью нашего экземпляра приложения мы можем задавать маршруты, основанные на HTTP-методах, в данном примере app.get().

var app = require('express').createServer();

app.get('/', function(req, res){
    res.send('hello world');
});

app.listen(3000);

Создание HTTPS-сервера

Чтобы инициализировать express.HTTPSServer, мы совершаем те же действия, что и выше, но к тому де передаем объект опций, содержащий ключ, сертификат и другие параметры, о которых написано в документации модуля https NodeJS.

var app = require('express').createServer({ key: ... });

Конфигурирование

Express поддерживает произвольные окружения (environments), как например, production и development. Разработчики могут использовать метод configure(), чтобы добавить нужные для данного окружения функции. Когда configure() вызывается без имени окружения, он будет срабатывать в любом окружении прежде чем сработает любой configure, в котором окружение задано.

В приведенном ниже примере мы просто используем опцию dumpExceptions и в режиме разработки выдаем клиенту в ответ стек-трейс исключения. В обоих же режимах мы используем прослойку methodOverride и bodyParser. Обратите внимание на использование app.router, который сам по себе позволяет монтировать маршруты — в противном случае они монтируются при первом вызове app.get(), app.post() и т.д.

app.configure(function(){
    app.use(express.methodOverride());
    app.use(express.bodyParser());
    app.use(app.router);
});

app.configure('development', function(){
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
    var oneYear = 31557600000;
    app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
    app.use(express.errorHandler());
});

Для окруженией со схожими настройками можно передавать несколько имен окружений:

app.configure('stage', 'prod', function(){
    // config
});

Для внутренних и произвольных настроек в Express есть методы set(key[, val]), enable(key), disable(key):

app.configure(function () {
    app.set('views', __dirname + '/views');
    app.set('views');
    // => "/absolute/path/to/views"
    app.enable('some feature');
    // все равно что app.set('some feature', true);
    app.disable('some feature');
    // все равно что app.set('some feature', false);
    app.enabled('some feature')
    // => false
});

Чтобы задать окружение мы можем установить переменную окружения NODE_ENV. Например:

NODE_ENV=production node app.js

Это очень важно, потому что множество механизмов кэширования включаются только в окружении production.

Настройки

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

  • home — базовый путь приложения, который используется для res.redirect(), а также для прозрачной поддержки примонтированных приложений.
  • views корневая директория представлений. По умолчанию текущая_папка/views
  • view engine — шаблонизатор по умолчанию для представлений, вызываемых без расширения файла.
  • view options — объект, отражающий глобальные опции представлений
  • view cache — включить кэширование представлений (включается в окружении production)
  • case sensitive routes — включить маршруты, чувствительные к регистру
  • strict routing — если включено, то завершающие слэши больше не игннорируются
  • jsonp callback — разрешить методу res.send() прозрачную поддержку JSONP

Маршрутизация

Express использует HTTP-методы для обеспечения осмысленного, выразительного API маршрутизации. Например, мы хотим, чтобы по запросу /user/12 отображался профиль пользователя с id=12. Для этого мы определяем привелденный ниже маршрут. Значения, связанные с именованными полями, доступны в объекте res.params.

app.get('/user/:id', function(req, res){
    res.send('user ' + req.params.id);
});

Маршрут это просто строка, которая внутри движка компилируется в регулярное выражение. Например, когда компилируется /user/:id, то получается регулярное выражение вроде такого:

\/user\/([^\/]+)\/?

Также можно сразу передавать регулярное выражение. Но поскольку группы в регулярных выражениях не именуются, к ним можно добраться в req.params по номерам. Так первая группа попадает в req.params[0], вторая в req.params[1] и т.д.

app.get(/^\/users?(?:\/(\d+)(?:\.\.(\d+))?)?/, function(req, res){
    res.send(req.params);
});

Теперь возьмем curl и пошлем запрос на вышеупомянутый маршрут:

curl http://dev:3000/user
# [null,null]
curl http://dev:3000/users
# [null,null]
curl http://dev:3000/users/1
# ["1",null]
curl http://dev:3000/users/1..15
# ["1","15"]

Ниже приведены несколько примеров маршрутов и пути, которые могут им соответствовать:

	"/user/:id"
	/user/12
	"/users/:id?"
	/users/5
	/users
	"/files/*"
	/files/jquery.js
	/files/javascripts/jquery.js
	"/file/*.*"
	/files/jquery.js
	/files/javascripts/jquery.js
	"/user/:id/:operation?"
	/user/1
	/user/1/edit
	"/products.:format"
	/products.json
	/products.xml
	"/products.:format?"
	/products.json
	/products.xml
	/products
	"/user/:id.:format?"
	/user/12
	/user/12.json

Например, мы можем послать POST-ом некоторый JSON и ответить тем же JSON-ом, используя прослойку bodyParser, который умеет парсить JSON запрос (как впрочем и другие запросы) и помещать ответ в req.body:

var express = require('express'),
    app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res) {
    res.send(req.body);
});
app.listen(3000);

Как правило мы используем «глупое» поле (например, /user/:id), у которого нет ограничений. Но если мы, к примеру, хотим ограничить ID пользователя только числовыми символами, можно использовать /user/:id([0-9]+). Такая конструкция не будет срабатывать, если значение поля содержит нечисловые символы.

Передача управления на другой маршрут

Вызвав третий аргумент — next(), можно передать управление на следующий маршрут. Если соответствие не найдено, управление передается назад в Connect, и прослойки продолжают вызываться в порядке, в котором они были включены с помощью use(). Так же работают несколько маршрутов, имеющих один и тот же путь. Они просто вызываются по очереди, до того момента, когда один их них ответит вместо того, чтобы вызвать next().

app.get('/users/:id?', function(req, res, next) {
    var id = req.params.id;
    if (id) {
        // делаем что-то
    } else {
        next();
    }
});

app.get('/users', function(req, res) {
    // делаем что-то другое
});

Метод app.all() полезен, если нужно выполнить одну и ту же логику для всех HTTP-методов. Ниже мы используем этот метод для извлечения юзера из базы данных и назначения его в req.user.

var express = require('express'),
    app = express.createServer();
var users = [{
    name: 'tj'
}];
app.all('/user/:id/:op?', function(req, res, next) {
    req.user = users[req.params.id];
    if (req.user) {
        next();
    } else {
        next(new Error('cannot find user ' + req.params.id));
    }
});

app.get('/user/:id', function(req, res) {
    res.send('viewing ' + req.user.name);
});

app.get('/user/:id/edit', function(req, res) {
    res.send('editing ' + req.user.name);
});

app.put('/user/:id', function(req, res) {
    res.send('updating ' + req.user.name);
});

app.get('*', function(req, res) {
    res.send('what???', 404);
});

app.listen(3000);

Прослойки

Прослойки фреймворка Connect можно передавать в express.createServer() точно так же, как если бы использовался обычный Connect-сервер. Например:

var express = require('express');
var app = express.createServer(
    express.logger(),
    express.bodyParser());

Так же можно использовать use(). Так удобнее добавлять прослойки внутри блоков configure(), что более прогрессивно.

app.use(express.logger({ format: ':method :url' }));

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

var connect = require('connect');
app.use(connect.logger());
app.use(connect.bodyParser());

Это не совсем удобно, поэтому Express повторно экспортирует Connect-овские прослойки:

app.use(express.logger());
app.use(express.bodyParser());

Порядок прослоек имеет значение. Так, когда Connect получает запрос, выполняется первая прослойка, добавленная через createServer() или use(). Она вызывается с тремя параметрами: request, response и callback-функция, обычно называемая next. когда вызывается next(), управление передается на вторую прослойку и т.д. Это важно учитывать, так так множество прослоек зависят друг от друга. Например methodOverride() обращается к req.body.method для перегрузки HTTP-метода, а bodyParser() парсит тело запроса, чтобы заполнить req.body. Другой пример — парсинг cookies и поддержка сессий — вначале необходимо вызывать use() для cookieParser(), затем для session().

Множество Express-приложений может иметь строчку app.use(app.router). Это может показаться странным, но это нужно просто для того, чтобы явным образом указать прослойку, которая включает в себя все созданные нами маршруты. Эту прослойку можно включать в любом порядке, хотя по умолчанию она включается в конце. Изменяя ее позицию, можно управлять очередностью ее выполнения. Например, нам нужен обработчик ошибок, который будет срабатывать после всех других прослоек и отображать любое исключение, переданное в него с помощью next(). Или же может понадобиться понизить очередность выполнения прослойки, обслуживающей статические файлы, чтобы позволить другим маршрутам перехватывать запросы к таким файлам и, например, считать количество скачиваний и т.д. Вот как это может выглядеть:

app.use(express.logger(...));
app.use(express.bodyParser(...));
app.use(express.cookieParser(...));
app.use(express.session(...));
app.use(app.router);
app.use(express.static(...));
app.use(express.errorHandler(...));

Сначала мы добавляет logger() — он будет оборачивать метод req.end(), чтобы предоставлять нам данные о скорости ответа. Потом мы парсим тело запроса (если таковое имеется), затем куки, далее сессию, чтобы req.session был уже определен, когда мы доберемся до маршрутов в app.router. Если, например, запрос GET /javascripts/jquery.js будет обрабатываться маршрутами, и мы не вызовем next(), то прослойа static() никогда не получит этот запрос. Однако, если мы определим маршрут, как показано ниже, можно будет записывать статистику, отклонять загрузки, списывать оплату за загрузки, и т.д.

var downloads = {};
app.use(app.router);
app.use(express.static(__dirname + '/public'));
app.get('/*', function(req, res, next) {
    var file = req.params[0];
    downloads[file] = downloads[file] || 0;
    downloads[file]++;
    next();
});

Маршруты-прослойки

Маршруты могут использовать маршрутные прослойки путем передачи методу дополнительных коллбэков (или массивов). Это полезно, если нужно ограничить доступ либо подгружать какие-либо данные перед использованием маршрута, и т.д.

Обычно асинхронное получение данных может выглядеть примерно как показано ниже (тут мы берем параметр :id и грузим данные юзера).

app.get('/user/:id', function(req, res, next) {
    loadUser(req.params.id, function(err, user) {
        if (err) return next(err);
        res.send('Viewing user ' + user.name);
    });
});

Чтобы придерживаться принципа DRY и повысить читабельность кода, можно организовать такую логику с помощью прослоек. Как можно заметить, абстрагируя логику с помощью прослоек, можно как добиться повторного использования прослоек, так и сделать код маршрута более красивым.

function loadUser(req, res, next) {
    // тут мы грузим юзера из базы данных
    var user = users[req.params.id];
    if (user) {
        req.user = user;
        next();
    } else {
        next(new Error('Failed to load user ' + req.params.id));
    }
}
app.get('/user/:id', loadUser, function(req, res) {
    res.send('Viewing user ' + req.user.name);
});

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

function andRestrictToSelf(req, res, next) {
    req.authenticatedUser.id == req.user.id ? next() : next(new Error('Unauthorized'));
}
app.get('/user/:id/edit', loadUser, andRestrictToSelf, function(req, res) {
    res.send('Editing user ' + req.user.name);
});

Принимая во внимание тот факт, что прослойки — это просто функции, можно написать функцию, которая бы возвращала прослойку (чтобы обеспечить еще более выразительное и гибкое решение), как показано ниже.

function andRestrictTo(role) {
    return function(req, res, next) {
        req.authenticatedUser.role == role ? next() : next(new Error('Unauthorized'));
    }
}
app.del('/user/:id', loadUser, andRestrictTo('admin'), function(req, res) {
    res.send('Deleted user ' + req.user.name);
});

Часто используемые «стеки» прослоек можно передавать как массивы произвольной глубины и древовидности (они будут применяться рекурсивно):

var a = [middleware1, middleware2],
    b = [middleware3, middleware4],
    all = [a, b];
app.get('/foo', a, function() {});
app.get('/bar', a, function() {});
app.get('/', a, middleware3, middleware4, function() {});
app.get('/', a, b, function() {});
app.get('/', all, function() {});

Полный пример можно посмотреть в репозитории.

Бывают случаи, когда надо пропустить остальные прослойки маршрута в стеке, но продолжить выполнение следующих маршрутов. Для этого надо вызывать next() с аргументом route: next("route"). Если не осталось маршрутов для выполнения, Express ответит ошибкой 404 Not Found.

HTTP-методы

Мы уже неоднократно пользовались app.get(), однако Express также предоставляет прочие HTTP-методы — app.post(), app.del() и т.д.

Самый распространенный пример использования POST — это отправка формы. В примере ниже мы просто делаем HTML-форму. А потом управление будет передаваться маршруту, который мы определим в следующем примере.

<form method="post" action="/">
    <input type="text" name="user[name]" />
    <input type="text" name="user[email]" />
    <input type="submit" value="Submit" />
</form>

По умолчанию Express не знает, что ему делать с телом запроса, поэтому мы должны добавить прослойку bodyParser(), которая будет парсить тело запроса, закодированное в application/x-www-form-urlencoded или application/json, и помещать результаты парсинга в req.body. Для этого мы должны сказать use(), как показано ниже:

app.use(express.bodyParser());

Теперь нижеприведенный маршрут будет иметь доступ к объекту req.body.user, у которого будут свойства name и email:

app.post('/', function(req, res) {
    console.log(req.body.user);
    res.redirect('back');
});

В случае использования формой таких методов как PUT, можно использовать скрытый инпут по имени _method, который позволяет изменить HTTP-метод. Чтобы этого добиться, нужно сначала задействовать прослойку methodOverride(), которая будет помещена после bodyParser(), что позволит ей использовать req.body, содержащий поля переданной формы.

app.use(express.bodyParser());
app.use(express.methodOverride());

Эти прослойки не задействованы по умолчанию, потому что Express не обязательно должен сразу обладать полным функционалом. В зависимости от нужд приложения, можно и не использовать их. И тогда методы PUT и DELETE все так же будут доступны, но уже напрямую. В то же вреям methodOverride — это отличное решение для HTML-форм. Ниже показан пример использования метода PUT:

<form method="post" action="/">
    <input type="hidden" name="_method" value="put" />
    <input type="text" name="user[name]" />
    <input type="text" name="user[email]" />
    <input type="submit" value="Submit" />
</form>
app.put('/', function() {
    console.log(req.body.user);
    res.redirect('back');
});

Обработка ошибок

У Express есть метод app.error(), который принимает все исключения, брошенные маршрутами, или переданные в виде next(err). Ниже пример, как обслуживать несколько страниц с использованием самодельного исключения NotFound:

function NotFound(msg) {
    this.name = 'NotFound';
    Error.call(this, msg);
    Error.captureStackTrace(this, arguments.callee);
}
NotFound.prototype.__proto__ = Error.prototype;
app.get('/404', function(req, res) {
    throw new NotFound;
});
app.get('/500', function(req, res) {
    throw new Error('keyboard cat!');
});

Можно вызывать app.error() несколько раз, как показано ниже. Тут мы проверяем instanceof NotFound и показываем страницу 404, или же передаем управление следующему обработчику ошибок.

Заметьте, что эти обработчики могут быть определены где угодно, поскольку они все равно будут помещены ниже обработчиков маршрутов в listen(). Это позволяет их определять внутри блоков configure(), так что можно обрабатывать исключения по-разному в зависимости от текущего окружения.

app.error(function(err, req, res, next) {
    if (err instanceof NotFound) {
        res.render('404.jade');
    } else {
        next(err);
    }
});

Для просто ты мы принимаем здесь, что все ошибки имеют код 500, но вы можете это изменить как угодно. Например когда Node делает операции с файловой системой, можно получить объект ошибки с полем error.code = ENOENT, что означает «не найден файл или директория», мы можем использовать это в обработчике ошибок и показывать соответствующую страницу.

app.error(function(err, req, res) {
    res.render('500.jade', {
        error: err
    });
});

Также приложения могут использовать для обработки исключений Connect-овскую прослойку errorHander. Например, если нужно в окружении development показывать исключения в stderr, можно сделать так:

app.use(express.errorHandler({ dumpExceptions: true }));

Также в ходе разработки нам могут понадобиться клевые HTML-странички, показывающие переданные или брошенные исключения. В таком случае нужно установить showStack в true:

app.use(express.errorHandler({ showStack: true, dumpExceptions: true }));

Прослойка errorHandler также отвечает в JSON, если клиентом передан заголовок Accept: application/json, что полезно для разработки AJAX-приложений.

Пред-обработки параметров маршрута

Пред-обработки параметров маршрута могут существенно улучшить читабельность приложения, через явную загрузку данных и валидацию URL запроса. Например, если вы постоянно извлекаете какие-то данные для определенных запросов (например грузите пользовательские данные для /user/:id), можно сделать что-то вроде этого:

app.get('/user/:userId', function(req, res, next) {
    User.get(req.params.userId, function(err, user) {
        if (err) return next(err);
        res.send('user ' + user.name);
    });
});

С пред-условиями на наши параметры запроса можно навесить callback-функции, которые бы выполняли валидацию, ограничене доступа, или даже загрузку данных из базы данных. В примере ниже мы вызываем app.param() с именем параметра, на который хотим навесить callback. Как можно заметить мы получаем аргумент id, который содержит имя поля. Таким образом мы загружаем объект пользователя и выполняем обычную обработку ошибок и простой вызов next(), чтобы передать управление на следующее пред-условие либо уже на обработчик маршрута.

app.param('userId', function(req, res, next, id) {
    User.get(id, function(err, user) {
        if (err) return next(err);
        if (!user) return next(new Error('failed to find user'));
        req.user = user;
        next();
    });
});

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

app.get('/user/:userId', function(req, res) {
    res.send('user ' + req.user.name);
});

Рендеринг представлений

Имена файлов представлений образуются по схеме {имя}.{движок}, где {движок} — это название модуля шаблонизатора, который должен быть подключен. Например представление layout.ejs говорит системе представлений, что надо сделать require('ejs'). Чтобы интегрироваться в Express, загружаемый модуль должен экспортировать метод exports.compile(str, options), и возвращать функцию. Чтобы изменить это поведение, можно пользоваться методом app.register() — он позволяет проассоциировать расширения файлов с определенными движками. Например можно сделать, чтобы foo.html рендерился движком ejs.

Ниже — пример, использующий Jade для рендеринга index.html. И поскольку мы не используем layout:false, отрендеренный контент представления index.jade будет передан как локальная переменная body в представление layout.jade.

app.get('/', function(req, res) {
    res.render('index.jade', {
        title: 'My Site'
    });
});

Настройка view engine позволяет указать шаблонизатор по умолчанию. Так например при использовании Jade можно сделать так:

app.set('view engine', 'jade');

что позволит нам рендерить так:

res.render('index');

, а не так:

res.render('index.jade');

Когда шаблонизатор установлен через view engine, расширения файлов не нужны. Однако мы по-прежнему можем использовать сразу несколько шаблонизаторов:

res.render('another-page.ejs');

В Express также есть настройка view options, которая будет накладываться при каждом рендеринге представления. Например если вы не так часто используете лэйауты, можно написать так:

app.set('view options', {
    layout: false
});

Что можно при необходимости потом перегрузить в вызове res.render():

res.render('myview.ejs', { layout: true });

Когда же нужен другой лэйаут, можно также указать путь. Например, если у нас view engine установлен в jade, и файл лэйаута называется ./views/mylayout.jade, можно просто передать:

res.render('page', { layout: 'mylayout' });

В противном случае можно передать расширение файла:

res.render('page', { layout: 'mylayout.jade' });

Пути могут быть также абсолютными:

res.render('page', { layout: __dirname + '/../../mylayout.jade' });

Хороший пример — это указание нестандартных открывающих и закрывающих тегов движка ejs:

app.set('view options', {
    open: '{{',
    close: '}}'
});

Фрагменты представлений

Система представлений Express имеет встроенную поддержку фрагментов и коллекций, своего рода мини-представлений. Например, вместо того, чтобы итерировать в представлении циклом для отображения списка комментариев, можно просто использовать фрагмент collection:

partial('comment', { collection: comments });

Если другие опции или локальные переменные не нужны, то можно пропустить объект и просто передать массив данных. Пример ниже равносилен предыдущему:

partial('comment', comments);

В случае использовании коллекций мы имеем несколько «волшебных» локальных переменных:

  • firstInCollectiontrue, если это первый объект
  • indexInCollection — индекс объекта в коллекции
  • lastInCollectiontrue, если это последний объект
  • collectionLength — длина коллекции

Переданные или сгенерированные локальные переменные имеет более высокий приоритет, однако локальные переменные, переданные в родительское представление, также доступны и в дочернем. Так например, если мы рендерим представление с помощью partial('blog/post', post) и оно породит локальную переменную post, а представление, вызвавшее эту функцию, имело локальную переменную user, то user также будет виден в представлении blog/post.

Дополнительную документацию см в разделе res.partial().

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

Поиск представлений

Поиск представлений производится относительно родительского преставления. Например если у нас есть представление views/user/list.jade и внутри него мы вызываем фрагмент partial('edit'), система попытается загрузить представление views/user/edit.jade, тогда как partial('../messages') приведет к загрузке views/messages.jade

Система представлений также позволяет делать index-файлы. Например, мы можем вызвать res.render('users'), и это может загрузить как views/users.jade, так и views/users/index.jade.

Использовать index-файлы можно также из представления в той же директории. Так вызовом partial('users') можно обратиться к представлению ../users/index вместо того чтобы вызывать partial('index').

Шаблонизаторы

Ниже представлены несколько шаблонизаторов, часто используемых с Express:

  • Haml
  • Jade
  • EJS — встроенный JavaScript
  • CoffeeKup — шаблонизация на основе CoffeeScript
  • jQuery Templates для Node

Поддержка сессий

Поддержку сессий можно включить используя Connect-овскую прослойку session. Также для этого нам нужна вышележащая прослойка cookieParser, которая будет парсить куки и помещать их в req.cookies.

app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));

По умолчанию прослойка session использует Connect-овское хранилище в памяти, однако существует множество других решений. Например connect-redis поддерживает хранилище сессий в Redis. Вот как им пользоваться:

var RedisStore = require('connect-redis')(express);
app.use(express.cookieParser());
app.use(express.session({
    secret: "keyboard cat",
    store: new RedisStore
}));

Теперь свойства req.session и req.sessionStore будут доступны из всех маршрутов и последующих прослоек. Свойства req.session автоматически сохраняются при ответе. Вот как можно организовать корзину:

var RedisStore = require('connect-redis')(express);
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
    secret: "keyboard cat",
    store: new RedisStore
}));
app.post('/add-to-cart', function(req, res) {
    // допустим мы передали из формы несколько объектов
    // используем для этого bodyParser()
    var items = req.body.items;
    req.session.items = items;
    res.redirect('back');
});
app.get('/add-to-cart', function(req, res) {
    // Когда мы редиректим назат на GET /add-to-cart
    // мы можем проверить req.session.items && req.session.items.length
    // чтобы распечатать наше сообщение
    if (req.session.items && req.session.items.length) {
        req.flash('info', 'You have %s items in your cart', req.session.items.length);
    }
    res.render('shopping-cart');
});

Объект req.session также имеет методы Session.touch(), Session.destroy(), Session.regenerate() для манипуляции сессиями. Для более полной информации см. документацию Connect Session.

Руководство по миграции

Разработчики, работавшие с Express 1.x могут обращаться к руководству по миграции, чтобы научить свои приложения работать с Express 2.x, Connect 1.x, и Node 0.4.x.

Request

req.header(key[, defaultValue])

Получить заголовок запроса key (нечувствительно к регистру) с необязательным значением по умолчанию DefaultValue:

req.header('Host');
req.header('host');
req.header('Accept', '*/*');

Заголовки Referrer и Referer — особый случай, обе конструкции будут работать:

// послан заголовок "Referrer: http://google.com"
req.header('Referer');
// => "http://google.com"
req.header('Referrer');
// => "http://google.com"

req.accepts(type)

Проверяет передан ли заголовок Accept, и подходит ли он под данный тип.

Когда заголовок Accept отсутствует, возвращается true. В противном случае проверяется соответствие типа, а потом подтипов. Можно передавать 'html' которое внутренне конвертируется в 'text/html', используя таблицу соответствия MIME.

// Accept: text/html
req.accepts('html');
// => true
// Accept: text/*; application/json
req.accepts('html');
req.accepts('text/html');
req.accepts('text/plain');
req.accepts('application/json');
// => true
req.accepts('image/png');
req.accepts('png');
// => false

req.is(type)

Проверяет входящий запрос на наличие заголовка Content-Type и соответствие заданному MIME-типу.

// Пусть Content-Type: text/html; charset=utf-8
req.is('html');
req.is('text/html');
// => true
// Пусть Content-Type теперь application/json
req.is('json');
req.is('application/json');
// => true
req.is('html');
// => false

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

app.is('an image', function(req) {
    return 0 == req.headers['content-type'].indexOf('image');
});

Теперь внутри обработчиков маршрутов можно использовать его, чтобы проверять Content-Type вида 'image/jpeg', 'image/png' и т.д.

app.post('/image/upload', function(req, res, next) {
    if (req.is('an image')) {
        // выполняем определенные действия
    } else {
        next();
    }
});

Не забывайте, что этот метод распространяется не только на Content-Type — вы можете делать любые проверки.

Также можно использовать подстановочные символы. Это упростит наш пример с изображением. Тут мы будем проверять только тип:

req.is('image/*');

Мы также можем также проверять подтип, как показано ниже. Тут проверка вернет true в случаях 'application/json', и 'text/json'.

req.is('*/json');

req.param(name[, default])

Возвращает значение параметра name или — если оно не существует — default.

Проверяет параметры маршрута (req.params), например, /user/:id

Проверяет параметры строки запроса (req.query), например, ?id=12

Проверяет urlencoded-параметры тела запроса (req.body), например, id=12

Чтобы получать urlencoded-параметры тела запроса, должен существовать объект req.body. Для этого включите прослойку bodyParser().

req.get(field, param)

Получает параметр поля заголовка. По умолчанию — пустая строка.

req.get('content-disposition', 'filename');
// => "something.png"
req.get('Content-Type', 'boundary');
// => "--foo-bar-baz"

req.flash(type[, msg])

Помещает всплывающее сообщение в очередь.

req.flash('info', 'email sent');
req.flash('error', 'email delivery failed');
req.flash('info', 'email re-sent');
// => 2
req.flash('info');
// => ['email sent', 'email re-sent']
req.flash('info');
// => []
req.flash();
// => { error: ['email delivery failed'], info: [] }

Всплывающие сообщения также могут использовать форматные строки. По умолчанию доступна строка '%s':

req.flash('info', 'email delivery to _%s_ from _%s_ failed.', toUser, fromUser);

req.isXMLHttpRequest

Также имеет сокращение req.xhr. Проверяет заголовок X-Requested-With на предмет того, что запрос сделан с помощью XMLHttpRequest:

req.xhr
req.isXMLHttpRequest

Response

res.header(key[, val])

Получает или устанавливает заголовок ответа.

res.header('Content-Length');
// => undefined
res.header('Content-Length', 123);
// => 123
res.header('Content-Length');
// => 123

res.charset

Устанавливает кодировку следующих заголовков Content-Type. Например, res.send() и res.render() по умолчанию будут "utf8", а мы можем явно задать кодировку перед тем как рендерить шаблон:

res.charset = 'ISO-8859-1';
res.render('users');

или перед тем, как отвечать с помощью res.send():

res.charset = 'ISO-8859-1';
res.send(str);

или с помощью встроенного в Node res.end():

res.charset = 'ISO-8859-1';
res.header('Content-Type', 'text/plain');
res.end(str);

res.contentType(type)

Устанавливает заголовок ответа Content-Type.

var filename = 'path/to/image.png';
res.contentType(filename);
// Content-Type теперь "image/png"

Можно задавать Content-Type и строкой:

res.contentType('application/json');

Или просто расширением файла (без ведущей точки):

res.contentType('json');

res.attachment([filename])

Устанавливает заголовок ответа Content-Disposition в "attachment". Опционально может быть передано имя файла.

res.attachment('path/to/my/image.png');

res.sendfile(path[, options[, callback]])

Используется в res.download() для передачи произвольного файла.

res.sendfile('path/to/my.file');

Этод метод принимает необязательный параметр callback, который вызывается в случае ошибки или успеха передачи файла. По умолчанию вызывается next(err), однако если передан callback, то надо это делать явно, или обрабатывать ошибку.

res.sendfile(path, function(err) {
    if (err) {
        next(err);
    } else {
        console.log('transferred %s', path);
    }
});

Также можно передавать опции вызову fs.createReadStream(). Например, чтобы изменить размер буфера:

res.sendfile(path, {
    bufferSize: 1024
}, function(err) {
    // обработка...
});

res.download(file[, filename[, callback[, callback2]]])

Передать данный файл как вложение (можно задать необязательное альтернативное имя файла).

res.download('path/to/image.png');
res.download('path/to/image.png', 'foo.png');

Это эквивалентно следующему:

res.attachment(file);
res.sendfile(file);

Опционально можно задать callback вторым или третьим аргументом res.sendfile(). Внутри него вы можете отвечать, как если бы заголовок еще не был передан.

res.download(path, 'expenses.doc', function(err) {
    // обработка...
});

Также можно опционально передать второй коллбэк — callback2. В нем обрабатываются ошибки, связанные с соединением. Однако в нем не следует пытаться посылать ответ.

res.download(path, function(err) {
    // ошибка или завершение
}, function(err) {
    // ошибка соединения
});

res.send(body|status[, headers|status[, status]])

Метод res.send() — высокоуровневое средство ответа, позволяющее передавать объекты (для JSON-ответа), строки (для HTML-ответа), экземпляры Buffer, или целые числа, определяющие статус-код (404, 500 и т.д.). Вот как это используется:

res.send(); // 204
res.send(new Buffer('wahoo'));
res.send({
    some: 'json'
});
res.send('<p>some html</p>');
res.send('Sorry, cant find that', 404);
res.send('text', {
    'Content-Type': 'text/plain'
}, 201);
res.send(404);

По умолчанию заголовок Content-Type устанавливается автоматически. Однако если он был вручную, явным образом задан в res.send() или перед этим с помощью res.header(), или с помощью res.contentType(), то автоматической установки не произойдет.

Заметьте, что в этом методе происходит завершение ответа (аналогично res.end()), поэтому, если нужно выдать множественный ответ, или поток, то нужнопользоваться res.write().

res.json(obj[, headers|status[, status]])

Посылает JSON-ответ с необязательными заголовками и статус-кодом. Этот метод идеален для организации JSON-API, однако JSON можно посылать также с помощью res.send(obj) (что впрочем не идеально, если нужно послать только строку, закодированную в JSON, так как res.send(string) отправит HTML)

res.json(null);
res.json({
    user: 'tj'
});
res.json('караул!', 500);
res.json('Ничего не найдено', 404);

res.redirect(url[, status])

Перенаправляет на заданный URL. Статус-код по умолчанию — 302.

res.redirect('/', 301);
res.redirect('/account');
res.redirect('http://google.com');
res.redirect('home');
res.redirect('back');

Express поддерживает сокращения для редиректов — по умолчанию это 'back' и 'home'. При этом 'back' перенаправляет на URL, заданный в заголовке Referrer (или Referer), а 'home' использует настройку "home" (по умолчанию "/").

res.cookie(name, val[, options])

Устанавливает значение cookie с именем name в val. Опции: httpOnly, secure, expires, и т.д. Опция path по умолчанию принимает значение, установленное в настройке "home", обычно это "/".

// "Запомнить меня" на 15 минут
res.cookie('rememberme', 'yes', {
    expires: new Date(Date.now() + 900000),
    httpOnly: true
});

Свойством maxAge можно задавать expire относительно Date.now() в миллисекундах. Таким образом наш вышеупомянутый пример теперь можно переписать так:

res.cookie('rememberme', 'yes', { maxAge: 900000 });

Чтобы парсить входящие куки, использйте прослойку cookieParser, которая формирует объект req.cookies:

app.use(express.cookieParser());
app.get('/', function(req, res) {
    // используем req.cookies.rememberme
});

res.clearCookie(name[, options])

Очищаем cookie по имени name, присваивая параметру expires дату в далеком прошлом. Опции те же, что у res.cookie(), path точно так же по умолчанию равен настройке "home".

res.clearCookie('rememberme');

res.render(view[, options[, fn]])

Рендерит представление view с заданными опциями options и необязательным коллбеком fn. Когда задана fn, ответ клиенту не происходит автоматически, в противном же случае делается ответ text/html с кодом 200.

Передаваемые опции являются по совместительству локальными переменными представления. Например, если мы хотим передать переменую user и запретить лэйаут, мы делаем это в одном объекте:

var user = {
    name: 'tj'
};
res.render('index', {
    layout: false,
    user: user
});

Также объект options служит для передачи опций. Например, если вы передаете свойство status, то оно не только становится доступно представлению, а также устанавливает статус-код ответа. Это также полезно, если шаблонизатор принимает определенные опции, например debug или compress. Ниже — пример того, как можно отрендерить страницу ошибки — тут передается status как для его отображения, так и для установки статус-кода res.statusCode.

res.render('error', { status: 500, message: 'Internal Server Error' });

res.partial(view[, options])

Рендерит фрагмент с заданными опциями. Этот метод всегда доступен из представления как локальная переменная.

  • object — объект, передаваемый в представление
  • as — имя переменной, которая будет представлять объект object или каждый элемент коллекции collection, переданных в представление. По умолчанию — имя представления.
    • as: 'something' — добавит локальную переменную something
    • as: this — будет использовать элемент коллекции как контекст представления (this)
    • as: global — сольёт воедино свойства элемента колекции и локальные переменные представления
    • collection — массив объектов. Имя его происходит из имени представления. Например video.html будет имметь внутри объект video.

Следующие конструкции эквивалентны друг другу и имя коллекции, переданное фрагменту, везде будет "movie".

partial('theatre/movie.jade', {
    collection: movies
});
partial('theatre/movie.jade', movies);
partial('movie.jade', {
    collection: movies
});
partial('movie.jade', movies);
partial('movie', movies);
// Внутри представления: moovie.director

Чтобы сменить имя локальной переменной с 'movie' на 'video', можно использовать опцию as:

partial('movie', {
    collection: movies,
    as: 'video'
});
// Внутри представления: video.director

Также мы можем сделать movie значением this внутри нашего представления, чтобы вместо movie.director можно было обращаться this.director.

partial('movie', {
    collection: movies,
    as: this
});
// Внутри представления: this.director

Альтернативное решение — это развернуть свойства элемента коллекции в псевдо-глобальные (на самом деле локальные) переменные, используя as: global, такой вот «синтаксический сахар»:

partial('movie', {
    collection: movies,
    as: global
});
// Внутри представления: director

Такая же логика применима не только к коллекциям, но и к объекту внутри фрагментного представления:

partial('movie', {
    object: movie,
    as: this
});
// Внутри представления: this.director
partial('movie', {
    object: movie,
    as: global
});
// Внутри представления: director
partial('movie', {
    object: movie,
    as: 'video'
});
// Внутри представления: video.director
partial('movie', {
    object: movie
});
// movie.director

Когда второй аргумент — не-коллекция (про признаку отсутствия .length), он считается объектом. При этом имя локальной переменной для этого объекта образуется из имени представления.

var movie = new Movie('Nightmare Before Christmas', 'Tim Burton')
partial('movie', movie)
// => Внутри представления: movie.director

Исключение из этого правила — это когда передается простой объект ("{}" или "new Object"), тогда он считается объектом с локальными переменными (прим перев.: и недоступен по имени внутри фрагментного представления). Например в следующем примере можно ожидать, что будет локальная переменная "movie", однако поскольку это простой объект, локальные переменные уже "director" и "title", то есть его свойства:

var movie = {
    title: 'Nightmare Before Christmas',
    director: 'Tim Burton'
};
partial('movie', movie)

Для таких случаев, когда нужно передавать именно простой объект, просто присвойте его какому-нибудь свойству, или используйте свойства object, которое унаследует имя объекта из имени файла. Перечисленные ниже примеры эквивалентны:

partial('movie', {
    locals: {
        movie: movie
    }
})
    partial('movie', {
    movie: movie
})
    partial('movie', {
    object: movie
})

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

app.get('/users', function(req, res) {
    if (req.xhr) {
        // передаем в ответ каждого юзера из коллекции
        // переданной в представление "user"
        res.partial('user', users);
    } else {
        // отвечаем полным лэйаутом со страницей списка пользователей
        // шаблон которой внутри себя делает partial('user', users)
        // ну и добавляет какой-то интерфейс
        res.render('users', {
            users: users
        });
    }
});

res.local(name[, val])

Получить или установить заданную локальную переменную. Под локальными переменными в данном случае имеются в виду переменные, передаваемые в методы рендеринга представления, например в res.render().

app.all('/movie/:id', function(req, res, next) {
    Movie.get(req.params.id, function(err, movie) {
        // Делает присваивание res.locals.movie = movie
        res.local('movie', movie);
    });
});
app.get('/movie/:id', function(req, res) {
    // локальная переменная movie уже есть
    // , но мы можем ее дополнить, если нужно
    res.render('movie', {
        displayReviews: true
    });
});

res.locals(obj)

Присвоить несколько локальных переменных с помощью данного объекта obj. Следующее эквивалентно:

res.local('foo', bar);
res.local('bar', baz);
res.locals({
    foo: bar,
    bar,
    baz
});

Server

app.set(name[, val])

Установить настройку приложение name в значение val, или получить значение настройки name, если val отсутствует:

app.set('views', __dirname + '/views');
app.set('views');
// => ...path...

Также можно добраться до настроек через appsettings:

app.settings.views
// => ...path...

app.enable(name)

Устанавливает настройку name в true:

app.enable('some arbitrary setting');
app.set('some arbitrary setting');
// => true
app.enabled('some arbitrary setting');
// => true

app.enabled(name)

Проверяет, равна ли true настройка name:

app.enabled('view cache');
// => false
app.enable('view cache');
app.enabled('view cache');
// => true

app.disable(name)

Установить настройку name в false:

app.disable('some setting');
app.set('some setting');
// => false
app.disabled('some setting');
// => false

app.disabled(name)

Проверяет, равна ли false настройка name:

app.enable('view cache');
app.disabled('view cache');
// => false
app.disable('view cache');
app.disabled('view cache');
// => true

app.configure(env|function[, function])

Задает коллбэк-функцию callback для окружения env (или для всех окружений):

app.configure(function() {
    // выполняется для всех окружений
});
app.configure('development', function() {
    // выполняется только для окружения 'development'
});

app.redirect(name, val)

Для res.redirect() мы можем определить сокращения (в области видимости приложения), как показано ниже:

app.redirect('google', 'http://google.com');

Теперь в маршруте мы можем вызвать:

res.redirect('google');

Также можно делать динамические сокращения:

app.redirect('comments', function(req, res) {
    return '/post/' + req.params.id + '/comments';
});

Теперь можно сделать следующее и редирект динамически построится в соответствие с контекстом запроса. Если мы вызвали маршрут с помощью GET /post/12, наш редирект будет /post/12/comments.

app.get('/post/:id', function(req, res) {
    res.redirect('comments');
});

В случае монтированного приложения res.redirect() будет учитывать точку монтирования приложения. Например, если блог-приложение смонтировано в /blog, следующий пример сделает редирект в /blog/posts:

res.redirect('/posts');

app.error(function)

Добавляет функцию-обработчик ошибок, которая первым параметром будет принимать все исключения, как показано ниже. Заметьте, что можно устанавливать несколько обработчиков ошибок, путем нескольких вызовов этого метода, однако метод должен вызывать next(), если он не хочет сам обрабатывать исключение:

app.error(function(err, req, res, next) {
    res.send(err.message, 500);
});

app.helpers(obj)

Регистрирует статические помощники представлений.

app.helpers({
    name: function(first, last) {
        return first + ', ' + last
    },
    firstName: 'tj',
    lastName: 'holowaychuk'
});

Наше представление может теперь пользоваться переменными firstName и lastName и функцией name().

<%= name(firstName, lastName) %>

Также Express предоставляет по умолчанию несколько локальных переменных:

  • settings — объект настроек приложения
  • layout(path) указать лэйаут прямо изнутри представления

Этот метод имеет псевдоним app.locals().

app.dynamicHelpers(obj)

Регистрирует динамические помощники представлений. Динамические помощники представлений — это просто функции, принимающие res, req и выполняемые в контексте экземпляра Server перед тем, как отрендерить любое представление. Возвращаемое значение такой функции становится локальной переменной, с которой функция ассоциирована.

app.dynamicHelpers({
    session: function(req, res) {
        return req.session;
    }
});

Теперь все наши представления будут иметь доступ к сессии — данные сессии будут доступны на манер session.name и т.д.:

<%= session.name %>

app.lookup

Возвращает обработчики маршрута, связанные с заданным путем path.

Допустим, есть такие маршруты:

app.get('/user/:id', function() {});
app.put('/user/:id', function() {});
app.get('/user/:id/:op?', function() {});

Можно использовать функционал lookup для проверки того, какие мрашруты заданы. Это может пригодиться для фреймворков более высокого уровня, построенных на Express.

app.lookup.get('/user/:id');
// => [Function]
app.lookup.get('/user/:id/:op?');
// => [Function]
app.lookup.put('/user/:id');
// => [Function]
app.lookup.all('/user/:id');
// => [Function, Function]
app.lookup.all('/hey');
// => []

Псевдонимом для app.lookup.HTTP_МЕТОД() является просто app.HTTP_МЕТОД() — без аргумента callback. Такое вот сокращение. Например следующее эквивалентно:

app.lookup.get('/user');
app.get('/user');

Каждая возвращенная функция дополняется полезными свойствами:

var fn = app.get('/user/:id/:op?')[0];
fn.regexp
// => /^\/user\/(?:([^\/]+?))(?:\/([^\/]+?))?\/?$/i
fn.keys
// => ['id', 'op']
fn.path
// => '/user/:id/:op?'
fn.method
// => 'GET'

app.match

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

Допустим, есть следующие маршруты:

app.get('/user/:id', function() {});
app.put('/user/:id', function() {});
app.get('/user/:id/:op?', function() {});

Вызов match для GET вернет две функции, поскольку :op в последнем маршруте необязательный параметр.

app.match.get('/user/1');
// => [Function, Function]

А следующий вызов вернет только один коллбэк для /user/:id/:op?.

app.match.get('/user/23/edit');
// => [Function]

Можно использовать и all(), если нам не важен HTTP-метод

app.match.all('/user/20');
// => [Function, Function, Function]

Каждая функция снабжается следующими свойствами:

var fn = app.match.get('/user/23/edit')[0];
fn.keys
// => ['id', 'op']
fn.params
// => { id: '23', op: 'edit' }
fn.method
// => 'GET'

app.mounted(fn)

Назначить коллбэк fn, который вызывается, когда этот Server передается в Server.use().

var app = express.createServer(),
    blog = express.createServer();
blog.mounted(function(parent) {
    //parent  - это app 
    // this - это blog
});
app.use(blog);

app.register(ext, exports)

Ассоциирует заданные экспортируемые свойства (exports) шаблонизатора с расширением ext файла шаблона.

app.register('.html', require('jade'));

Также это может пригодиться в случае с библиотеками, имя которых не совпадает в точности с расширением файла шаблона. Живой пример — Haml.js, который устанавливается npm-ом как "hamljs", а мы можем зарегистрировать его на шаблоны ".haml", а не ".hamljs", как было бы по умолчанию:

app.register('.haml', require('haml-js'));

Кроме того app.register очень помогает в случае с шаблонизаторами, API которых не соответствует спецификациям Express. В примере ниже мы ассоциируем расширение .md с рендерером markdown-файлов. Рендерить в HTML будем только первый раз — для большей производительности — и будем поддерживать подстановку переменных вида "{name}".

app.register('.md', {
    compile: function(str, options) {
        var html = md.toHTML(str);
        return function(locals) {
            return html.replace(/\{([^}]+)\}/g, function(_, name) {
                return locals[name];
            });
        };
    }
});

app.listen([port[, host]])

Биндим сокет сервера app к адресу host:port. Порт по умолчанию 3000, хост — INADDR_ANY.

app.listen();
app.listen(3000);
app.listen(3000, 'n.n.n.n');

Аргумент port может быть также строкой, представляющей собой путь к unix domain socket:

app.listen('/tmp/express.sock');

Теперь попробуем:

telnet /tmp/express.sock
# GET / HTTP/1.1
# HTTP/1.1 200 OK
# Content-Type: text/plain
# Content-Length: 11
# Hello World

Участники проекта

Основной вклад в проект внесли следующие лица:

  • TJ Holowaychuk (visionmedia)
  • Ciaran Jessup (ciaranj)
  • Aaron Heckmann (aheckmann)
  • Guillermo Rauch (guille)

Сторонние модули

Следующие модули работают с Express или построены на его основе:

  • express-resource обеспечивает ресурсную маршрутизацию
  • express-messages рендеринг всплывающих уведомлений
  • express-configure поддержка асинхронной конфигурации (загрузка данных из Redis, и т.д.)
  • express-namespace — пространства имен в маршрутах
  • express-expose простая публикация JS-кода в клиентскую часть приложения
  • express-params — расширения app.param()
  • express-mongoose — плагин для простого рендеринга результатов запросов Mongoose (ORM для MongoDB)

Прочая информация

  • #express на freenode
  • Следите за tjholowaychuk в Твиттере
  • Google Group
  • Wiki
  • 日本語ドキュメンテーション by hideyukisaito
  • Русскоязычная документация

Как разработать полноценный сервер в Express

Введение

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

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

К концу этого пошагового руководства у вас будет четкое представление о том, как создать API CRUD (создание, чтение, обновление, удаление) с помощью Express.

Что такое CRUD API?

CRUD API — это набор операций, упрощающих создание, поиск, обновление и удаление данных в базе данных. Он служит интерфейсом между внешним интерфейсом приложения и серверной базой данных.

С помощью CRUD API разработчики могут беспрепятственно выполнять эти основные операции, позволяя манипулировать данными с помощью HTTP-запросов.

Зачем использовать Экспресс?

Express — широко распространенная платформа веб-приложений для Node.js благодаря своей простоте, гибкости и отличной производительности. Вот несколько веских причин выбрать Express для разработки API:

  1. Минималистичный: Express придерживается минималистского подхода, позволяя разработчикам быстро и эффективно создавать API. Он предоставляет простой, но мощный набор функций, что делает его идеальным выбором как для небольших, так и для крупномасштабных проектов.
  2. Надежное промежуточное ПО: Express предлагает систему промежуточного ПО, которая упрощает обработку запросов и позволяет реализовать пользовательские функции. Функции промежуточного ПО можно использовать для таких задач, как аутентификация, проверка данных, обработка ошибок и многое другое.
  3. Расширяемость: Express можно легко расширить с помощью дополнительных пакетов и модулей из обширной экосистемы Node.js. Эта гибкость позволяет разработчикам без особых усилий расширять свои API различными функциями и интеграциями.
  4. Удобство для разработчиков: Express может похвастаться хорошо документированным API и активным сообществом, что упрощает поиск поддержки и ресурсов. Его простота и интуитивно понятный дизайн позволяют разработчикам сосредоточиться на создании основных функций своих API, не увязая в ненужных сложностях.

Пошаговое руководство: создание CRUD API в Express

Прежде чем мы углубимся в код, убедитесь, что на вашем компьютере установлены Node.js и npm (диспетчер пакетов Node). Начнем с настройки проекта и установки необходимых зависимостей.

Шаг 1. Настройка проекта

Создайте новый каталог для своего проекта и перейдите к нему с помощью командной строки. Выполните следующую команду, чтобы инициализировать новый проект Node.js:

$ npm init -y

Эта команда создает файл package.json, в котором будут храниться метаданные и зависимости проекта. Далее установим Express и другие необходимые пакеты:

$ npm install express body-parser mongoose

Шаг 2. Настройка экспресс-сервера

Создайте новый файл с именем server.js и импортируйте необходимые модули:

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');

const app = express();
const port = process.env.PORT || 3000;
// Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Start the server
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

В этом фрагменте кода мы импортируем Express, body-parser и mongoose. Мы создаем экземпляр приложения Express, устанавливаем порт для прослушивания и добавляем промежуточное ПО для разбора тела запроса.

Шаг 3. Установка подключения к MongoDB

Чтобы взаимодействовать с базой данных MongoDB, нам нужно настроить соединение с помощью библиотеки mongoose. Добавьте следующий код в файл server.js:

const mongoURI = 'mongodb://localhost/crud-api';
mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true });

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', () => {
  console.log('Connected to MongoDB');
});

В этом фрагменте кода мы указываем URI подключения MongoDB и устанавливаем соединение, используя mongoose.connect(). Мы также настроили прослушиватели событий для обработки ошибок подключения и регистрации успешного подключения.

Шаг 4. Определение модели данных

Далее давайте определим модель данных для нашего API. Создайте новый файл с именем models.js и добавьте следующий код:

javascriptCopy code
const mongoose = require('mongoose');

const Schema = mongoose.Schema;
const ItemSchema = new Schema({
  name: { type: String, required: true },
  description: { type: String },
  price: { type: Number, required: true },
});
module.exports = mongoose.model('Item', ItemSchema);

В этом коде мы определяем схему мангуста с такими полями, как name, description и price для наших элементов. Оператор module.exports экспортирует модель, позволяя нам использовать ее в других частях нашего приложения.

Шаг 5: Реализация операций CRUD

Теперь давайте реализуем операции CRUD для нашего API. Добавьте следующий код в файл server.js:

const Item = require('./models');

// Create item
app.post('/items', (req, res) => {
  const newItem = new Item(req.body);
  newItem.save((err, item) => {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.status(201).json(item);
    }
  });
});
// Read items
app.get('/items', (req, res) => {
  Item.find({}, (err, items) => {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.json(items);
    }
  });
});
// Update item
app.put('/items/:id', (req, res) => {
  const itemId = req.params.id;
  const update = req.body;
  Item.findByIdAndUpdate(itemId, update, { new: true }, (err, item) => {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.json(item);
    }
  });
});
// Delete item
app.delete('/items/:id', (req, res) => {
  const itemId = req.params.id;
  Item.findByIdAndRemove(itemId, (err, item) => {
    if (err) {
      res.status(500).json({ error: err.message });
    } else {
      res.sendStatus(204);
    }
  });
});

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

Шаг 6. Тестирование API

Поздравляем! Вы успешно внедрили CRUD API с помощью Express. Запустите сервер, выполнив следующую команду:

$ node server.js

Теперь вы можете тестировать конечные точки API с помощью таких инструментов, как Postman или cURL. Вот некоторые примеры:

  • Чтобы создать новый элемент, отправьте запрос POST на адрес http://localhost:3000/items, указав сведения об элементе в теле запроса.
  • Чтобы получить все элементы, отправьте запрос GET на http://localhost:3000/items.
  • Чтобы обновить элемент, отправьте запрос PUT на http://localhost:3000/items/{id} с обновленными сведениями об элементе в теле запроса.
  • Чтобы удалить элемент, отправьте запрос DELETE на http://localhost:3000/items/{id}.

Не забудьте заменить {id} фактическим идентификатором элемента, который вы хотите обновить или удалить.

Заключение

В этом руководстве мы рассмотрели процесс создания CRUD API с помощью Express, мощной платформы веб-приложений для Node.js. Мы обсудили концепцию CRUD API и преимущества использования Express, а также прошли пошаговую реализацию API.

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

Разработка API с помощью Express открывает целый мир возможностей, позволяя создавать масштабируемые и эффективные веб-сервисы. Так что вперед, запачкайте руки и начните изучать потенциал JavaScript, создав собственный CRUD API с помощью Express.

Не забывайте практиковаться и изучать различные функции и возможности Express, чтобы улучшить свои навыки разработки API. Удачного кодирования!

Примечание. Убедитесь, что вы правильно применяете меры безопасности и проверки подлинности при развертывании API в рабочих средах.

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .

Airport Express — это небольшое, но мощное устройство, разработанное компанией Apple, которое позволяет создать беспроводную сеть Wi-Fi у себя дома или в офисе. Если вы хотите установить Airport Express и настроить его для работы, вам потребуется следовать подробной инструкции, которую мы представляем в этой статье.

Шаг 1: Подключите устройство

В первую очередь, подключите Airport Express к вашему роутеру или модему с использованием Ethernet-кабеля. Убедитесь, что вход в интернет работает и что кабель подключен правильно.

Шаг 2: Настройте Airport Express

Подключите свой персональный компьютер или ноутбук к Airport Express через Wi-Fi или Ethernet-кабель. Затем откройте AirPort Utility на вашем устройстве. Если у вас нет этой утилиты, вы можете загрузить ее с официального сайта Apple.

Шаг 3: Создайте новую сеть или присоединитесь к существующей

Теперь вы можете настроить свою сеть Airport Express. Если вы хотите создать новую беспроводную сеть, выберите «Создать новую беспроводную сеть» и следуйте инструкциям. Если вы хотите присоединиться к существующей сети, выберите «Присоединиться к существующей сети» и введите настройки вашей сети.

Шаг 4: Настройте дополнительные параметры

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

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

Изучаем, как настроить Airport Express

Шаг 1: Подготовка к установке

Перед началом настройки Airport Express вам понадобятся следующие элементы:

  • Устройство Airport Express
  • Интернет-провайдер и активное подключение к Интернету
  • Компьютер или устройство с поддержкой Wi-Fi для конфигурации Airport Express
  • Интернет-браузер (рекомендуется Safari или Google Chrome)

Шаг 2: Подключение Airport Express

Подключите Airport Express к электрической сети и подключите его к модему или маршрутизатору с помощью кабеля Ethernet.

Шаг 3: Настройка Airport Express

Откройте приложение «Airport Утилита» на вашем компьютере или устройстве, подключенном к Wi-Fi.

Нажмите на кнопку «Продолжить», чтобы начать процесс настройки.

Выберите «Настроить новое устройство Airport» и нажмите «Далее».

Выберите «Airport Express» и нажмите «Далее».

Выберите «Создать новую сеть Wi-Fi» и введите имя сети (SSID) и пароль.

Выберите «Обновлять автоматически» в списке доступных обновлений программного обеспечения и нажмите «Далее».

Нажмите «Применить», чтобы сохранить настройки.

Шаг 4: Подключение к сети Airport Express

На вашем компьютере или устройстве откройте список доступных Wi-Fi сетей и выберите название сети, которое вы указали на предыдущем шаге.

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

Теперь вы подключились к сети Airport Express и можете использовать интернет.

Обратите внимание: при настройке Airport Express вы можете изменить другие параметры, такие как безопасность сети, DHCP и порты USB. Рекомендуется обращаться к руководству пользователя Airport Утилита для получения дополнительной информации.

Sql Server Express — бесплатная реляционная система управления базами данных, разработанная компанией Microsoft. Эта версия программы предоставляет все основные возможности SQL Server, но ограничена в области масштабирования и производительности.

Если вам необходимо установить и настроить Sql Server Express, следуйте этой пошаговой инструкции:

  1. Скачайте и запустите установочный файл: Перейдите на официальный сайт Microsoft, найдите раздел Sql Server Express и скачайте соответствующую версию установочного файла. Запустите скачанный файл и следуйте инструкциям мастера установки.
  2. Выберите тип установки: В процессе установки вы получите возможность выбрать тип установки. Рекомендуется выбрать «Типичная установка», чтобы установить все необходимые компоненты Sql Server Express.
  3. Настройте параметры экземпляра: Далее вам потребуется настроить параметры экземпляра. Укажите имя экземпляра, выберите тип аутентификации (Windows или SQL Server) и установите пароль для администратора.
  4. Укажите настройки сети: В следующем окне мастера установки Sql Server Express укажите настройки сети. Выберите протоколы, которые будут использоваться для подключения к базе данных, и установите порт для соединения.
  5. Укажите директории данных: Последний шаг установки — укажите директории данных, где будут храниться файлы баз данных. Вы можете использовать значения по умолчанию или выбрать свои собственные директории.

После завершения установки вам потребуется перезагрузить компьютер. Затем вы сможете запустить Sql Server Express и начать работу с базами данных. Помните, что вам потребуется использовать правильные параметры подключения для доступа к базе данных.

Важно помнить, что Sql Server Express имеет определенные ограничения в области масштабирования и производительности. Если вам требуются более продвинутые функции и возможности, рассмотрите возможность использования полноценной версии SQL Server.

Содержание

  1. Sql Server Express: установка и активация
  2. Установка Sql Server Express
  3. Активация Sql Server Express
  4. Шаг 1: Скачайте Sql Server Express
  5. Шаг 2: Установка Sql Server Express

Sql Server Express: установка и активация

Для начала работы с Sql Server Express необходимо выполнить два основных этапа: установку и активацию. Ниже представлены пошаговые инструкции по каждому из этих этапов.

Установка Sql Server Express

  1. Скачайте установочный файл Sql Server Express с официального сайта Microsoft.
  2. Запустите установочный файл и следуйте инструкциям мастера установки.
  3. Выберите тип установки (в данном случае Express Edition) и нажмите кнопку «Далее».
  4. Примите условия лицензионного соглашения и нажмите кнопку «Далее».
  5. Укажите папку, в которую будет установлен Sql Server Express, и нажмите кнопку «Далее».
  6. Выберите компоненты, которые вы хотите установить (обычно выбираются все компоненты по умолчанию) и нажмите кнопку «Установить».
  7. Дождитесь завершения установки и закройте мастер установки.

Активация Sql Server Express

  1. Откройте программу Sql Server Management Studio (SSMS).
  2. Введите имя сервера (обычно localhost или .\SQLEXPRESS) и выберите тип аутентификации (обычно Windows аутентификация).
  3. Нажмите кнопку «Подключиться» для подключения к серверу.
  4. В левой панели SSMS выберите «Серверы» и перейдите к «Объекту» -> «Движку баз данных».
  5. Создайте новую базу данных или выберите существующую базу данных для работы.
  6. Теперь Sql Server Express готов к использованию.

Шаг 1: Скачайте Sql Server Express

  1. Откройте веб-браузер и перейдите на официальный сайт Microsoft.
  2. В поисковой строке введите «Sql Server Express» и нажмите Enter. Это откроет страницу загрузки Sql Server Express.
  3. На странице загрузки найдите раздел «Sql Server Express» и выберите нужную версию программы. Обратите внимание на требования к системе и выберите версию, которая соответствует вашим потребностям и возможностям вашей системы.
  4. Нажмите на ссылку для скачивания выбранной версии Sql Server Express.
  5. Дождитесь завершения загрузки файла.

Поздравляю, вы успешно скачали Sql Server Express! Теперь вы готовы перейти к следующему шагу — установке программы.

Шаг 2: Установка Sql Server Express

После скачивания файла установки Sql Server Express с официального сайта Microsoft, перейдите к его запуску. Для этого щелкните дважды по загруженному файлу.

На экране появится окно с вопросом, хотите ли вы разрешить программе внести изменения на ваш компьютер. Щелкните «Да», чтобы продолжить установку.

В следующем окне вам будет предложено выбрать тип установки. Если вы планируете использовать Sql Server Express в качестве сервера баз данных, выберите «Установить сервер и инструменты». Если вам нужен только клиентский инструмент, выберите «Установить только инструменты». Щелкните «Далее», чтобы продолжить.

Затем вам будет предложено принять лицензионное соглашение. Ознакомьтесь с ним и, если вы согласны со всеми условиями, выберите «Я принимаю условия этого соглашения». Щелкните «Далее», чтобы продолжить.

На следующем экране вам может быть предложено выбрать компоненты, которые вы хотите установить. Если вы не знаете, какие компоненты выбрать, оставьте предлагаемые по умолчанию. Щелкните «Далее», чтобы продолжить.

В следующем окне вам будет предложено выбрать каталог установки. Если вы хотите использовать каталог по умолчанию, оставьте его без изменений. Щелкните «Далее», чтобы продолжить.

Затем вам будет предложено выбрать экземпляр Sql Server. Если вы планируете использовать только один экземпляр, выберите «DefaultInstance». Если вы хотите создать новый экземпляр, выберите «NamedInstance» и введите его имя. Щелкните «Далее», чтобы продолжить.

На следующем экране вам может быть предложено выбрать тип сети, который будет использоваться Sql Server Express. Если вы не знаете, что выбрать, оставьте выбранным вариант «Только для сетей IPv4». Щелкните «Далее», чтобы продолжить.

Затем вам может быть предложено выбрать аккаунт службы Sql Server. Если вы не знаете, что выбрать, оставьте выбранным вариант «Пользователь системы NT: NetworkService». Щелкните «Далее», чтобы продолжить.

На следующем экране вы можете выбрать режим установки. Если вы хотите иметь возможность настроить Sql Server в будущем, выберите вариант «Многократная установка». Если же вы просто хотите выполнить базовую установку, выберите вариант «Минимальная установка». Щелкните «Далее», чтобы продолжить.

Во время установки Sql Server Express вам может быть предложено установить обновления и дополнительные компоненты. Если вы хотите установить все доступные обновления и компоненты, выберите вариант «Установить все предлагаемые обновления и дополнительные компоненты». Если вы не хотите устанавливать обновления и компоненты сейчас, выберите вариант «Не устанавливать дополнительные компоненты». Щелкните «Далее», чтобы продолжить.

Затем вам будет предложено выбрать тип аутентификации. Если вы планируете использовать Windows-аутентификацию, выберите «Windows-аутентификация». Если вы хотите использовать SQL Server-аутентификацию, выберите «Mixed Mode». Задайте пароль для учетной записи «sa». Щелкните «Далее», чтобы продолжить.

На последнем экране вы увидите сводку выбранных параметров для установки Sql Server Express. Проверьте все настройки и щелкните «Установить», чтобы начать процесс установки.

После завершения установки вы увидите сообщение о том, что установка Sql Server Express успешно завершена. Щелкните «Готово», чтобы закончить установку.

Теперь у вас установлен Sql Server Express, и вы можете перейти к следующему шагу настройки.

Понравилась статья? Поделить с друзьями:
  • Инструкция браун парогенератор carestyle 3 по применению на русском
  • Руководство по ремонту volvo s60 на русском
  • Инструкция по применению орвирем сироп детям дозировка
  • Evion 400 инструкция по применению индия
  • Узормед макси поли инструкция по применению