Express для Node.js, основы

Oct 13, 2018

Коды ответов сервера

Список кодов состояния HTTP на wikipedia

кодназваниеописание
200OKsuccess
206Partial Contentиспользуется расширенными инструментами кэширования
301Moved Permanentlyзапрашиваемый ресурс был перемещен
302Foundрасположение запрашиваемого ресурса временно изменено
304Not Modifiedнет необходимости повторно передавать запрошенные ресурсы. Это неявное перенаправление на кэшированный ресурс.
401Unauthorizedпользователь не авторизован, попытка авторизации была отклонена
403Forbiddenзапрещено или доступ к ресурсу, к которому у пользователя нет доступа
404Not Foundзапрошенный ресурс не найден
500Internal Server Errorвнутренняя ошибка сервера

Методы ответа сервера express.js

  • res.download() - приглашение загрузить файл
  • res.end() - завершение ответа
  • res.json() - ответ в формате JSON
  • res.jsonp() - ответ в формате JSON с поддержкой JSONP
  • res.redirect() - редирект
  • res.render()- вывод шаблона представления
  • res.send() - отправка ответов различных типов
  • res.sendFile() - отправка файла в виде потока откетов
  • res.sendStatus() - установка кода состояния ответа и отправка представления в виде строки в качестве тела ответа

Шаблонизаторы в express.js

app.js

// указываем путь к основному шаблону
app.set('views', './views/pug');
// указываем какой шаблонизатор используем
app.set('view engine', 'pug');


app.get('*', (req, res) => {
    console.log('--- ', req.url);
    // после установки предыдущих команд, res.render понимает, как ему рендерить шаблон
    res.render('index', { title: 'Main Title', message: 'Hello' });
});

index.pug

html
    head
        title= title
    body
        h1= message

Промежуточное ПО / Middleware

Middleware - это функции, имеющие доступ к объекту запроса (req), объекту ответа (res) и к следующей функции промежуточной обработки в цикле 'запрос-ответ' приложения.

Для middleware особенно важен порядок простановки в скрипте.

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

Middleware обычно используются для подключения функционала и работы с куками, сессиями, с парсингом POST-запросов, логированием.

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

// Middleware
app.use(function (req, res, next) {
    console.log('Current Time:', Date.now());
    next();
});

app.get('/', function (req, res) {
    res.send('My first App!')
});

app.listen(3000)

middleware как второй параметр

middleware isAdmin будет выполнен перед запросом на '/secret'.

const isAdmin = (req, res, next) => {
    if (req.session.isAdmin) {
        return next();
    }
    res.redirect('/');
};

router.get('/secret', isAdmin, (req, res, next) => {
    res.render('pages/secret');
});

Получение параметров запроса

post / req.body

Для обработки POST-запросов нам потребуется middleware:

import * as bodyParser from 'body-parser';

const app = express();

app.use(bodyParser.json());

// этим мы делаем доступным объект req.body (ну а в нем поля формы)
app.use(bodyParser.urlencoded({ extended: false }));

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

get / req.query

req.query - это объект, который содержит соответствующее для каждого параметра строки запроса (/test?test=test, получаем как req.query.test) запроса в маршруте.

Именованные параметры маршрутизации / req.params

router.route('/articles/:category') получаем как req.params.category.

Конфиг

dotenv

Получаем данные через dotenv из файла prod-dev.env непосредственно в скрипте:

if (process.env.NODE_ENV == 'production') {
    console.log('THIS IS PROD [app.ts]');
    dotenv.load({ path: path.join(process.cwd(), 'prod.env') });
}  else if (process.env.NODE_ENV == 'development') {
    console.log('THIS IS DEV [app.ts]');
    dotenv.load({ path: 'prod-dev.env' });
}

где process.env.NODE_ENV ставится webpack посредством --mode=production

Храним тестовые данные: lowdb

lowdb (на github) - небольшая локальная JSON база данных. Может работать как на стороне сервера, так и на стороне клиента (localStorage).

Храним тестовые данные: nconf

nconf (на github) - храним данные в json-файле. Есть метод set при помощи которого задаем переменные, а также save, который позволяет сохранить конфигурационный объект.

const nconf = require('nconf');
const path = require('path');

module.exports = function () {
    return nconf
        .argv()
        .env()
        .file({file: path.join(__dirname, 'my-db.json')});
}
const db = require('../models/db')();

//...
db.set(fields.name, dir);
db.save();

Сессии (основы, express-session)

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

Подключаем пакет express-session.

Настраиваем сессию при помощу пакета express-session, далее добавляем сессии переменную views:

const session = require('express-session');

app.use(session({
    secret: 'secretWord',   // секретное слово для шифрования
    key: 'key',             // имя куки
    cookie: {
        path: '/',          // где действует
        httpOnly: true,     // чтобы куку не могли читать на клиенте
        maxAge: null        // время жизни куки
    },
    saveUninitialized: false,   // on default
    resave: false               // on  default
}));



app.all('/', function (req, res, next) {

    // в независимости от логина или нет получаем id
    console.log(req.session.id);

    // в сессию мы можем проставлять кастомные переменные
    req.session.views = req.session.views === void 0
        ? 0
        : req.session.views;
    req.session.views++;
    next();
})

Простая система управления доступом к страницам сайта на основе req.session.isAdmin, которую ставим на основе простого post-запроса:

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

const isAdmin = (req, res, next) => {
    // если в сессии текущего пользователя есть пометка о том, что он является
    // администратором
    if (req.session.isAdmin) {
        // то всё хорошо :)
        return next();
    }
    // если нет, то перебросить пользователя на главную страницу сайта
    res.redirect('/');
};

router.get('/', (req, res, next) => {
    res.render('pages/index', {title: 'My session', views: req.session.views});
});

router.post('/', (req, res, next) => {
    req.session.isAdmin = true;
    res.redirect('/secret');
});

router.get('/secret', isAdmin, (req, res, next) => {
    res.render('pages/secret');
});

module.exports = router;

generator express

npm install -g express-generator

У express есть генератор, наподобие CLI у Angular, который позволяет быстро создать каркас приложение. Устанавливается глобально (появляется команда express).

express -h

Посредством которой при генерации приложения на express.js вы можете выбрать движок (pug), и т.д.

express --view=pug --git test-myapp

Сгенерированное приложение отличается от обычного, например, запуском:

// приложение экспортируется через module.exports
    module.exports = app;

    // запуск в package.json посредством
    "start": "node ./bin/www"

    // для dev-режима поменять на
    "start": "nodemon ./bin/www"

    // это сделано так как node.js однопоточная, но у сервере может быть несколько ядер (в зависимости от того какой мы возьмем кластер для VDS)
    // то есть, данный запуск связан с тем, что мы подключили кластеризацию
Добавить комментарий