freeCodeCamp/guide/russian/nodejs/express/index.md

528 lines
39 KiB
Markdown
Raw Normal View History

2018-10-12 20:00:59 +00:00
---
title: ExpressJS
localeTitle: ExpressJS
---
## ExpressJS
Когда дело доходит до создания веб-приложений с использованием Node.js, создание сервера может занять много времени. На протяжении многих лет Node.js созрела из-за поддержки со стороны сообщества. Использование Node.js в качестве бэкэнд для веб-приложений и веб-сайтов помогает разработчикам быстро начать работу над своим приложением или продуктом. В этом уроке мы рассмотрим Expressjs, который представляет собой инфраструктуру Node.js для веб-разработки, которая включает такие функции, как маршрутизация и рендеринг и поддержка API REST.
## Что такое экспресс?
Express - самая популярная инфраструктура Node.js, потому что она требует минимальной настройки для запуска приложения или API, а также быстрой и неизолированной в одно и то же время. Другими словами, он не применяет свою собственную философию, что приложение или API должны быть построены определенным образом, в отличие от Rails и Django. Его гибкость может быть рассчитана по количеству доступных модулей `npm` что делает его одновременно подключаемым. Если у вас есть базовые знания HTML, CSS и JavaScript, и как Node.js работает в целом, вы в кратчайшие сроки сможете начать работу с Expressjs.
Express был разработан TJ Holowaychuk и теперь поддерживается фондом Node.js и разработчиками с открытым исходным кодом. Чтобы начать работу с использованием Express, вам необходимо установить Node.js и npm. Вы можете установить [Node.js](https://nodejs.org/en/) на свой локальный компьютер, а вместе с ним появится утилита командной строки `npm` , которая поможет нам установить плагины или так называемые зависимости позже в нашем проекте.
Чтобы проверить, правильно ли установлено все, откройте терминал и введите:
```shell
node --version
v5.0.0
npm --version
3.5.2
```
Если вы получаете номер версии вместо ошибки, это означает, что вы успешно установили Node.js и npm.
## Зачем использовать Expressjs?
Прежде чем мы начнем с механизма использования Express в качестве базовой структуры, давайте сначала рассмотрим, почему мы должны рассматривать это использование или причины его популярности.
* Express позволяет создавать одностраничные, многостраничные и гибридные веб-приложения и мобильные приложения. Другим распространенным использованием бэкэнд является предоставление API для клиента (будь то веб-сайт или мобильный).
* Он поставляется с механизмом шаблонов по умолчанию, Jade, который помогает облегчить поток данных в структуру веб-сайта и поддерживает другие механизмы шаблонов.
* Он поддерживает MVC (Model-View-Controller), очень распространенную архитектуру для разработки веб-приложений.
* Это межплатформенная платформа и не ограничивается какой-либо конкретной операционной системой.
* Он использует однополюсную и асинхронную модель Node.js.
Всякий раз, когда мы создаем проект с использованием `npm` , наш проект должен иметь файл `package.json` .
### Создание package.json
Файл JSON (JavaScript Object Notation) содержит всю информацию о любом проекте Express. Количество установленных модулей, название проекта, версия и другая метаинформация. Чтобы добавить Expressjs в качестве модуля в наш проект, сначала нам нужно создать каталог проекта, а затем создать файл package.json.
```shell
mkdir express-app-example
cd express-app-example
npm init --yes
```
Это создаст файл `package.json` в корне каталога проекта. Чтобы установить любой модуль из `npm` нам нужно иметь файл `package.json` в этом каталоге.
```json
{
"name": "express-web-app",
"version": "0.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"license": "MIT"
}
```
### Установка Express
Теперь у нас есть файл `package.json` , мы можем установить Express, выполнив команду:
```shell
npm install --save express
```
Мы можем подтвердить, что Express правильно установлен двумя способами. Во-первых, будет новый раздел в файле `package.json` именами `dependencies` под которыми существует наш Express:
```json
{
"name": "express-web-app",
"version": "0.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"license": "MIT",
"dependencies": {
"express": "4.16.0"
}
}
```
Второй способ заключается в том, что новая папка с именем `node_modules` неожиданно появилась в корне каталога проекта. В этой папке хранятся пакеты, которые мы устанавливаем локально в нашем проекте.
## Создание сервера с помощью Express
Чтобы использовать наш установленный пакет для платформы Express и создать простое серверное приложение, мы создадим файл `index.js` в корне каталога нашего проекта.
```javascript
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(3000, () => console.log('Example app listening on port 3000!'));
```
Чтобы запустить сервер, перейдите к своему терминалу и введите:
```shell
node index.js
```
Это запустит сервер. Это приложение с минимальным размером будет прослушивать порт 3000. Мы делаем запрос через наш браузер по `http://localhost:3000` и наш сервер будет отвечать `Hello World` на который браузер является клиентом, и там будет показано сообщение.
Первая строка нашего кода использует функцию `require` для включения `express` модуля. Вот как мы включаем и используем пакет, установленный из npm в любом файле JavaScript в нашем проекте. Прежде чем мы начнем использовать Express, нам нужно определить экземпляр, который обрабатывает запрос и ответ от сервера клиенту. В нашем случае это переменное `app` .
`app.get()` - это функция, которая сообщает серверу, что делать, когда вызывается запрос `get` по данному маршруту. Он имеет функцию обратного вызова `(req, res)` которые прослушивают входящий запрос `req` объект и соответственно отвечают с использованием объекта ответа `res` . Как `req` и `res` предоставляются нам в рамках Express.
Объект `req` представляет HTTP-запрос и имеет свойства для строки запроса запроса, параметров, тела и HTTP-заголовков. Объект res представляет ответ HTTP, отправляемый экспресс-приложением, когда он получает HTTP-запрос. В нашем случае мы отправляем текст `Hello World` всякий раз, когда делается запрос на маршрут `/` .
Наконец, `app.listen()` - это функция, которая запускает порт и хост, в нашем случае - `localhost` для соединений для прослушивания входящих запросов от клиента. Мы можем определить номер порта, например `3000` .
## Анатомия экспресс-приложения
Типичная структура файла сервера Express скорее всего будет содержать следующие части:
**зависимости**
Импортирование зависимостей, таких как само выражение. Эти зависимости устанавливаются с использованием `npm` как в предыдущем примере.
**Instantiations**
Это инструкции для создания объекта. Чтобы использовать экспресс, мы должны создать экземпляр переменной `app` из него.
**Конфигурации**
Эти инструкции являются настраиваемыми настройками на основе приложений, которые определены после экземпляров или определены в отдельном файле (подробнее об этом при обсуждении структуры проекта) и требуются в нашем основном файле сервера.
**Промежуточное**
Эти функции определяют поток цикла запроса-ответа. Они выполняются после каждого входящего запроса. Мы также можем определить пользовательские функции промежуточного программного обеспечения. У нас есть раздел о них ниже.
**Маршруты**
Это конечные точки, определенные на нашем сервере, которые помогают выполнять операции для конкретного запроса клиента.
**Загрузочный сервер**
Последним, которое выполняется на сервере Express, является `app.listen()` которая запускает наш сервер.
Теперь мы начнем разделять разделы, о которых мы ранее не говорили.
## маршрутизация
Маршрутизация относится к тому, как приложение на стороне сервера отвечает на запрос клиента на конкретную конечную точку. Эта конечная точка состоит из URI (путь, например `/` или `/books` ), и HTTP-метод, такой как GET, POST, PUT, DELETE и т. Д.
Маршруты могут быть либо старыми старыми веб-страницами, либо конечными точками API REST. В обоих случаях синтаксис аналогичного синтаксиса для маршрута может быть определен как:
```javascript
app.METHOD(PATH, HANDLER);
```
Маршрутизаторы помогают разделить проблемы, такие как разные конечные точки, и сохранить соответствующие части исходного кода вместе. Они помогают в создании поддерживаемого кода. Все маршруты определяются перед вызовом функции `app.listen()` . В типичном экспресс-приложении `app.listen()` будет последней выполняемой функцией.
### Методы маршрутизации
HTTP - это стандартный протокол для клиента и сервер для связи. Он предоставляет различные методы для запроса клиента. Каждый маршрут имеет по крайней мере функцию hanlder или обратный вызов. Эта функция обратного вызова определяет, какой будет ответ от сервера для этого конкретного маршрута. Например, маршрут `app.get()` используется для обработки запросов GET и в ответ посылает простое сообщение в виде ответа.
```javascript
// GET method route
app.get('/', (req, res) => res.send('Hello World!'));
```
### Пути маршрутизации
Путь маршрутизации представляет собой комбинацию метода запроса для определения конечных точек, по которым клиент может делать запросы. Пути маршрута могут быть строками, строковыми шаблонами или регулярными выражениями.
Определим еще две конечные точки в нашем серверном приложении.
```javascript
app.get('/home', (req, res) => {
res.send('Home Page');
});
app.get('/about', (req, res) => {
res.send('About');
});
```
Рассмотрим приведенный выше код как минимальный веб-сайт с двумя конечными точками, `/home` и `/about` . Если клиент делает запрос на домашней странице, то это будет только ответ с `Home Page` и `/about` будет отправлять ответ: `About Page` . Мы используем функцию `res.send` для отправки строки обратно клиенту, если выбран один из двух указанных маршрутов.
### Параметры маршрутизации
Параметры маршрута называются сегментами URL, которые используются для захвата значений, указанных в их позиции в URL-адресе. `req.params` этом случае используется объект `req.params` поскольку он имеет доступ ко всем параметрам, переданным в URL-адресе.
```javascript
app.get('/books/:bookId', (req, res) => {
res.send(req.params);
});
```
URL-адрес запроса от клиента в исходном коде будет `http://localhost:3000/books/23` . Имя параметров маршрута должно состоять из символов (\[A-Za-z0-9\_\]). Очень общий пример использования параметра маршрутизации в нашем приложении - это 404 маршрута.
```javascript
// For invalid routes
app.get('*', (req, res) => {
res.send('404! This is an invalid URL.');
});
```
Если теперь мы запустим сервер из командной строки с помощью `node index.js` и попробуем посетить URL-адрес: `http://localhost:3000/abcd` . В ответ мы получим сообщение 404.
## Функции промежуточного программного обеспечения
Функции промежуточного программного обеспечения - это те функции, которые имеют доступ к объекту запроса ( `req` ), объекту ответа ( `res` ) и `next` функции в цикле запроса-ответа приложения. Цель этих функций состоит в том, чтобы модифицировать объекты запроса и ответа для таких задач, как разбор тел запроса, добавление заголовков ответа, внесение других изменений в цикл запроса-ответа, завершение цикла запроса-ответа и вызов следующей функции промежуточного программного обеспечения.
`next` функция - это функция в маршрутизаторе Express, которая используется для выполнения других функций промежуточного программного обеспечения, следующих за текущим промежуточным программным обеспечением. Если функция промежуточного программного обеспечения включает `next()` это означает, что цикл запроса-ответа заканчивается там. Название функции `next()` здесь абсолютно произвольно, и вы можете называть его как угодно, но важно придерживаться лучших практик и пытаться следовать нескольким соглашениям, особенно если вы работаете с другими разработчиками.
Кроме того, при написании специального промежуточного программного обеспечения не забывайте добавлять к нему функцию `next()` . Если вы не укажете `next()` цикл запроса-ответа будет зависать посредине нигде, и ваш сервлет может привести к тайм-ауту клиента.
Позвольте использовать создание специальной функции промежуточного программного обеспечения, чтобы понять понимание этой концепции. Возьмите этот код, например:
```javascript
const express = require('express');
const app = express();
// Simple request time logger
app.use((req, res, next) => {
console.log("A new request received at " + Date.now());
// This function call tells that more processing is
// required for the current request and is in the next middleware
function/route handler.
next();
});
app.get('/home', (req, res) => {
res.send('Home Page');
});
app.get('/about', (req, res) => {
res.send('About Page');
});
app.listen(3000, () => console.log('Example app listening on port 3000!'));
```
Чтобы настроить любое промежуточное программное обеспечение, будь то пользовательское или доступное в качестве модуля npm, мы используем `app.use()` . Это как один необязательный путь параметра и один обязательный параметр обратного вызова. В нашем случае мы не используем необязательный путь параматера.
```javascript
app.use((req, res, next) => {
console.log('A new request received at ' + Date.now());
next();
});
```
Вышеупомянутая промежуточная функция вызывается для каждого запроса, сделанного клиентом. При запуске сервера вы заметите, что для каждого запроса на браузер в конечной точке `/` вы получите приглашение с сообщением в вашем терминале:
```shell
A new request received at 1467267512545
```
Функции промежуточного программного обеспечения могут использоваться для определенного маршрута. См. Пример ниже:
```javascript
const express = require('express');
const app = express();
//Simple request time logger for a specific route
app.use('/home', (req, res, next) => {
console.log('A new request received at ' + Date.now());
next();
});
app.get('/home', (req, res) => {
res.send('Home Page');
});
app.get('/about', (req, res) => {
res.send('About Page');
});
app.listen(3000, () => console.log('Example app listening on port 3000!'));
```
На этот раз вы увидите только аналогичное приглашение, когда клиент запросит конечную точку `/home` поскольку маршрут указан в `app.use()` . Ничего не будет показано в терминале, когда клиент запрашивает конечную точку `/about` .
Порядок функций промежуточного программного обеспечения важен, поскольку они определяют, когда вызывать функцию промежуточного программного обеспечения. В нашем примере выше, если мы определяем маршрут `app.get('/home')...` до промежуточного приложения `app.use('/home')...` , функция промежуточного программного обеспечения не будет вызываться.
### Функции промежуточного программного обеспечения третьей стороны
Функции промежуточного программного обеспечения - это полезный шаблон, который позволяет разработчикам повторно использовать код в своих приложениях и даже передавать его другим пользователям в виде модулей NPM. Существенным определением промежуточного программного обеспечения является функция с тремя аргументами: request (или req), response (res) и следующая, которую мы наблюдаем в предыдущем разделе.
Часто в нашем серверном приложении на основе Express мы будем использовать функции промежуточного программного обеспечения третьей стороны. Эти функции предоставляются самим Экспрессом. Они похожи на плагины, которые можно установить с помощью npm, и поэтому Express является гибким.
Некоторые из наиболее часто используемых функций промежуточного программного обеспечения в приложении Express:
#### bodyParser
Он позволяет разработчикам обрабатывать входящие данные, такие как полезная нагрузка тела. Полезная нагрузка - это всего лишь данные, которые мы получаем от клиента для обработки. Наиболее полезно с методами POST. Он устанавливается с использованием:
```shell
npm install --save body-parser
```
Применение:
```javascript
const bodyParser = require('body-parser');
// To parse URL encoded data
app.use(bodyParser.urlencoded({ extended: false }));
// To parse json data
app.use(bodyParser.json());
```
Вероятно, это одна из наиболее используемых сторонних функций промежуточного программного обеспечения в любом приложении Express.
#### cookieParser
Он анализирует заголовок Cookie и заполняет `req.cookies` с помощью объекта, управляемого именами `req.cookies` cookie. Чтобы установить его,
```shell
$ npm install --save cookie-parser
```
```javascript
const cookieParser = require('cookie-parser');
app.use(cookieParser());
```
#### сессия
Эта промежуточная функция создает промежуточное ПО сеанса с заданными параметрами. Сеанс часто используется в таких приложениях, как login / signup.
```shell
$ npm install --save session
```
```javascript
app.use(
session({
secret: 'arbitary-string',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
})
);
```
### Морган
Средство Morgan отслеживает все запросы и другую важную информацию в зависимости от указанного формата вывода.
```shell
npm install --save morgan
```
```javascript
const logger = require('morgan');
// ... Configurations
app.use(logger('common'));
```
`common` - это префиксный формат, который вы можете использовать в приложении. Существуют и другие предопределенные форматы, такие как крошечные и dev, но вы также можете определить собственный собственный формат, используя параметры строки, доступные нам morgan.
Список наиболее часто используемых функций промежуточного слоя доступен по этой [ссылке](https://expressjs.com/en/resources/middleware.html) .
## Обслуживание статических файлов
Чтобы обслуживать статические файлы, такие как таблицы стилей CSS, изображения и т. Д. Express предоставляет встроенную функцию промежуточного программного обеспечения `express.static` . Статические файлы - это те файлы, которые клиент загружает с сервера.
Это единственная функция промежуточного программного обеспечения, которая поставляется с платформой Express, и мы можем использовать ее непосредственно в нашем приложении. Все остальные посредники являются сторонними.
По умолчанию Express не позволяет обслуживать статические файлы. Мы должны использовать эту функцию промежуточного программного обеспечения. Общей практикой в ​​разработке веб-приложения является сохранение всех статических файлов в «общедоступном» каталоге в корне проекта. Мы можем обслуживать эту папку для обслуживания статических файлов, включая запись в нашем файле `index.js` :
```javascript
app.use(express.static('public'));
```
Теперь будут загружены статические файлы в нашем общедоступном каталоге.
```shell
http://localhost:3000/css/style.css
http://localhost:3000/images/logo.png
http://localhost:3000/images/bg.png
http://localhost:3000/index.html
```
### Несколько статических каталогов
Чтобы использовать несколько каталогов статических активов, несколько раз вызовите функцию промежуточного программного обеспечения `express.static` :
```javascript
app.use(express.static('public'));
app.use(express.static('files'));
```
### Префикс виртуального пути
Префикс исправления пути также может быть предоставлен в качестве первого аргумента функции промежуточного программного обеспечения `express.static` . Это называется _префикс виртуального пути,_ поскольку фактический путь не существует в проекте.
```javascript
app.use('/static', express.static('public'));
```
Если мы попытаемся загрузить файлы:
```shell
http://localhost:3000/static/css/style.css
http://localhost:3000/static/images/logo.png
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/index.html
```
Этот метод пригодится при предоставлении нескольких каталогов для обслуживания статических файлов. Префиксы используются для различения нескольких каталогов.
## Шаблоны
Механизмы шаблонов - это библиотеки, которые позволяют нам использовать разные языки шаблонов. Язык шаблона - это специальный набор инструкций (синтаксис и структуры управления), который инструктирует движок обрабатывать данные. Использование механизма шаблона легко с помощью Express. Популярные шаблоны, такие как Pug, EJS, Swig и Handlebars, совместимы с Express. Однако Express поставляется с механизмом шаблонов по умолчанию, Jade, который является первой выпущенной версией Pug.
Чтобы продемонстрировать, как использовать шаблонный движок, мы будем использовать Pug. Это мощный механизм шаблонов, который предоставляет такие функции, как фильтры, включает в себя, интерполяцию и т. Д. Чтобы использовать его, мы должны сначала установить в качестве модуля в нашем проекте, используя `npm` .
```shell
npm install --save pug
```
Эта команда установит мопс и проверяет правильность установки, просто взгляните на файл `package.json` . Чтобы сначала использовать его в нашем приложении, мы должны установить его как механизм шаблона и создать новый каталог «./views», где мы будем хранить все файлы, связанные с нашим механизмом шаблонов.
```javascript
app.set('view engine', 'pug');
app.set('views', './views');
```
Поскольку мы используем `app.set()` который указывает конфигурацию в нашем файле сервера, мы должны поместить их, прежде чем мы определим какой-либо маршрут или функцию промежуточного программного обеспечения.
В `views` directcotry создайте файл с именем `index.pug` .
```pug
doctype html
html
head
tite="Hello from Pug"
body
p.greetings Hello World!
```
Чтобы запустить эту страницу, мы добавим следующий маршрут в наше приложение.
```javascript
app.get('/hello', (req, res) => {
res.render('index');
});
```
Поскольку мы уже установили Pug в качестве нашего механизма шаблонов, в `res.render` нам не нужно предоставлять расширение `.pug` . Эта функция отображает код в любом `.pug` файле в HTML для отображения клиента. Браузеры могут отображать только HTML-файлы. Если вы запустите сервер сейчас и заходите на маршрут `http://localhost:3000/hello` вы увидите корректный вывод `Hello World` .
В Pug вы должны заметить, что нам не нужно писать закрывающие теги для элементов, как в HTML. Вышеприведенный код будет отображаться в HTML как:
```html
<!DOCTYPE html>
<html>
<head>
<title>Hello from Pug</title>
</head>
<body>
<p class = "greetings">Hello World!</p>
</body>
</html>
```
Преимущество использования шаблона Engine над необработанными HTML-файлами заключается в том, что они обеспечивают поддержку для выполнения задач над данными. HTML не может отображать данные напрямую. Рамочные устройства, такие как Angular and React, используют это поведение при использовании шаблонов.
Вы также можете передавать значения в механизм шаблонов непосредственно из функции обработчика маршрута.
```javascript
app.get('/', (req, res) => {
res.render('index', { title: 'Hello from Pug', message: 'Hello World!' });
});
```
Для вышеуказанного случая наш файл `index.pug` будет записан как:
```pug
doctype html
html
head
title= title
body
h1= message
```
Результат будет таким же, как в предыдущем случае.
## Структура проекта экспресс-приложения
Поскольку Express не очень сильно влияет на использование его разработчиком, иногда он может немного подавить структуру проекта, которой следует следовать. Он не имеет определенной структуры официально, но наиболее распространенным случаем использования, на котором применяется любое приложение на основе Node.js, является разделение различных задач в разных модулях. Это означает, что у вас есть отдельные файлы JavaScript.
Давайте рассмотрим типичную структуру веб-приложения на основе Express.
```
project-root/
node_modules/ // This is where the packages installed are stored
config/
db.js // Database connection and configuration
credentials.js // Passwords/API keys for external services used by your app
config.js // Environment variables
models/ // For mongoose schemas
books.js
things.js
routes/ // All routes for different entities in different files
books.js
things.js
views/
index.pug
404.pug
...
public/ // All static files
images/
css/
javascript/
app.js
routes.js // Require all routes in this and then require this file in
app.js
package.json
```
Это шаблон, обычно известный как MVC, model-view-controller. Просто потому, что наша модель базы данных, пользовательский интерфейс приложения и контроллеры (в нашем случае, маршруты) записываются и хранятся в отдельных файлах. Этот шаблон проектирования, который делает любое веб-приложение простым в масштабировании, если вы хотите ввести больше маршрутов или статических файлов в будущем, а код можно обслуживать.