Поиск…


Вступление

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

Официальный сайт Express - expressjs.com . Источник можно найти на GitHub .

Синтаксис

  • app.get (путь [, промежуточное ПО], обратный вызов [, обратный вызов ...])
  • app.put (путь [, промежуточное ПО], обратный вызов [, обратный вызов ...])
  • app.post (путь [, промежуточное ПО], обратный вызов [, обратный вызов ...])
  • app ['delete'] (путь [, промежуточное ПО], обратный вызов [, обратный вызов ...])
  • app.use (путь [, промежуточное ПО], обратный вызов [, обратный вызов ...])
  • app.use (обратный вызов)

параметры

параметр подробности
path Определяет участок пути или URL-адрес, который обрабатывает данный обратный вызов.
middleware Одна или несколько функций, которые будут вызываться перед обратным вызовом. По сути, это цепочка нескольких функций callback . Полезно для более конкретной обработки, например авторизации или обработки ошибок.
callback Функция, которая будет использоваться для обработки запросов к указанному path . Он будет называться как callback(request, response, next) , где request , response и next описаны ниже.
request обратного вызова Объект, инкапсулирующий данные о HTTP-запросе, вызываемые для обратного вызова.
response Объект, который используется для указания того, как сервер должен отвечать на запрос.
next Обратный вызов, который передает управление на следующий соответствующий маршрут. Он принимает необязательный объект ошибки.

Начиная

Сначала вам нужно создать каталог, получить доступ к нему в своей оболочке и установить Express с помощью npm , выполнив npm install express --save

Создайте файл и назовите его app.js и добавьте следующий код, который создает новый Express-сервер и добавляет к нему одну конечную точку ( /ping ) с app.get метода app.get :

const express = require('express');

const app = express();

app.get('/ping', (request, response) => {
    response.send('pong');
});

app.listen(8080, 'localhost');

Для запуска скрипта используйте следующую команду в своей оболочке:

> node app.js

Приложение будет принимать соединения на локальном порту 8080. Если аргумент hostname в app.listen опущен, сервер будет принимать соединения на IP-адресе компьютера, а также на localhost. Если значение порта равно 0, операционная система назначит доступный порт.

Как только ваш скрипт запущен, вы можете протестировать его в оболочке, чтобы подтвердить, что вы получаете ожидаемый ответ «понг» с сервера:

> curl http://localhost:8080/ping
pong

Вы также можете открыть веб-браузер, перейти к URL- адресу http: // localhost: 8080 / ping для просмотра вывода

Базовая маршрутизация

Сначала создайте экспресс-приложение:

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

Затем вы можете определить маршруты следующим образом:

app.get('/someUri', function (req, res, next) {})

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

// GET www.domain.com/myPath
app.get('/myPath', function (req, res, next) {})

// POST www.domain.com/myPath
app.post('/myPath', function (req, res, next) {})

// PUT www.domain.com/myPath
app.put('/myPath', function (req, res, next) {})

// DELETE www.domain.com/myPath
app.delete('/myPath', function (req, res, next) {})

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

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

или же

app.use('/myPath', function (req, res, next) {})

или же

app.use('*', function (req, res, next) {})

// * wildcard will route for all paths

Вы можете связать определения маршрута по одному пути

app.route('/myPath')
  .get(function (req, res, next) {})
  .post(function (req, res, next) {})
  .put(function (req, res, next) {})

Вы также можете добавлять функции к любому HTTP-методу. Они будут выполняться перед окончательным обратным вызовом и принимать параметры (req, res, next) в качестве аргументов.

// GET www.domain.com/myPath
app.get('/myPath', myFunction, function (req, res, next) {})

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

// other.js
exports.doSomething = function(req, res, next) {/* do some stuff */};

А затем в файле, содержащем ваши маршруты:

const other = require('./other.js');
app.get('/someUri', myFunction, other.doSomething);

Это сделает ваш код намного чище.

Получение информации из запроса

Чтобы получить информацию с запрашивающего URL-адреса (обратите внимание, что req является объектом запроса в функции обработчика маршрутов). Рассмотрим это определение маршрута /settings/:user_id и этот конкретный пример /settings/32135?field=name

// get the full path
req.originalUrl // => /settings/32135?field=name

// get the user_id param
req.params.user_id // => 32135     

// get the query value of the field
req.query.field // => 'name'

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

req.get('Content-Type')
// "text/plain"

Чтобы упростить получение другой информации, вы можете использовать middlewares. Например, чтобы получить информацию о теле запроса, вы можете использовать промежуточное программное обеспечение body-parser , которое преобразует необработанный модуль запроса в удобный формат.

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

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

Теперь предположим, что запрос такой

PUT /settings/32135
{
  "name": "Peter"
}

Вы можете получить доступ к опубликованному имени, как это

req.body.name
// "Peter"

Аналогичным образом вы можете получить доступ к файлам cookie из запроса, вам также понадобится промежуточное программное обеспечение, такое как cookie-parser

req.cookies.name

Модульное экспресс-приложение

Чтобы сделать экспресс-веб-приложение модульным заводом-изготовителем маршрутизаторов:

Модуль:

// greet.js
const express = require('express');

module.exports = function(options = {}) { // Router factory
    const router = express.Router();

    router.get('/greet', (req, res, next) => {
        res.end(options.greeting);
    });

    return router;
};

Заявка:

// app.js
const express = require('express');
const greetMiddleware = require('./greet.js');

express()
    .use('/api/v1/', greetMiddleware({ greeting:'Hello world' }))
    .listen(8080);

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

При доступе к http://<hostname>:8080/api/v1/greet вывод будет Hello world

Более сложный пример

Пример с услугами, которые показывают преимущества фабрики промежуточного ПО.

Модуль:

// greet.js
const express = require('express');

module.exports = function(options = {}) { // Router factory
    const router = express.Router();
    // Get controller
    const {service} = options;

    router.get('/greet', (req, res, next) => {
        res.end(
            service.createGreeting(req.query.name || 'Stranger')
        );
    });

    return router;
};

Заявка:

// app.js
const express = require('express');
const greetMiddleware = require('./greet.js');

class GreetingService {
    constructor(greeting = 'Hello') {
        this.greeting = greeting;
    }

    createGreeting(name) {
        return `${this.greeting}, ${name}!`;
    }
}

express()
    .use('/api/v1/service1', greetMiddleware({
        service: new GreetingService('Hello'),
    }))
    .use('/api/v1/service2', greetMiddleware({
        service: new GreetingService('Hi'),
    }))
    .listen(8080);

При доступе к http://<hostname>:8080/api/v1/service1/greet?name=World вывод будет Hello, World и доступ к http://<hostname>:8080/api/v1/service2/greet?name=World выход будет Hi, World .

Использование механизма шаблонов

Использование механизма шаблонов

Следующий код установит Jade в качестве механизма шаблонов. (Примечание: Джейд был переименован в pug состоянию на декабрь 2015 года.)

const express = require('express');  //Imports the express module
const app = express();  //Creates an instance of the express module

const PORT = 3000; //Randomly chosen port

app.set('view engine','jade'); //Sets jade as the View Engine / Template Engine
app.set('views','src/views'); //Sets the directory where all the views (.jade files) are stored.

//Creates a Root Route
app.get('/',function(req, res){
    res.render('index');  //renders the index.jade file into html and returns as a response. The render function optionally takes the data to pass to the view.
});

//Starts the Express server with a callback
app.listen(PORT, function(err) {
    if (!err) {
        console.log('Server is running at port', PORT);
    } else {
        console.log(JSON.stringify(err));
    }
});

Аналогичным образом могут использоваться и другие шаблонные двигатели, такие как Handlebars ( hbs ) или ejs . Не забудьте также npm install механизм шаблонов. Для Handlebars мы используем пакет hbs , для Jade у нас есть пакет jade и для EJS у нас есть пакет ejs .

Пример шаблона EJS

С помощью EJS (например, других экспресс-шаблонов) вы можете запускать код сервера и получать доступ к своим переменным сервера из HTML.
В EJS это делается с помощью « <% » в качестве начального тега и « %> » в качестве конечного тега, переменные, переданные в качестве параметров рендеринга, могут быть доступны с помощью <%=var_name%>
Например, если у вас есть массив поставок в коде сервера
вы можете

<h1><%= title %></h1>
   <ul>
<% for(var i=0; i<supplies.length; i++) { %>
    <li>
        <a href='supplies/<%= supplies[i] %>'>
            <%= supplies[i] %>
        </a>
    </li>
<% } %>

Как вы можете видеть в этом примере каждый раз, когда вы переключаетесь между кодом на стороне сервера и HTML, вам нужно закрыть текущий тег EJS и открыть новый позже, здесь мы хотели создать li внутри команды for поэтому нам нужно было закрыть наш тег EJS в конце for и создайте новый тег только для фигурных скобок
другой пример
если мы хотим, чтобы входная версия по умолчанию была переменной с серверной стороны, мы используем <%=
например:

 Message:<br>
<input type="text" value="<%= message %>" name="message" required>

Здесь переменная сообщения, переданная со стороны вашего сервера, будет значением по умолчанию для вашего ввода, обратите внимание, что если вы не передали переменную сообщения со своей серверной части, EJS выдаст исключение. Вы можете передавать параметры с помощью res.render('index', {message: message}); (для файла ejs, называемого index.ejs).

В тегах EJS вы также можете использовать if , while или любую другую команду javascript, которую вы хотите.

API JSON с ExpressJS

var express = require('express');
var cors = require('cors'); // Use cors module for enable Cross-origin resource sharing

var app = express();
app.use(cors()); // for all routes

var port = process.env.PORT || 8080;

app.get('/', function(req, res) {
    var info = {
        'string_value': 'StackOverflow',
        'number_value': 8476
    }
    res.json(info);

    // or
    /* res.send(JSON.stringify({
        string_value: 'StackOverflow',
        number_value: 8476
    })) */

  //you can add a status code to the json response
   /* res.status(200).json(info) */
})

app.listen(port, function() {
    console.log('Node.js listening on port ' + port)
})

В http://localhost:8080/ выходной объект

{
    string_value: "StackOverflow",
    number_value: 8476
}

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

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

Например, у вас могут быть index.html и script.js, которые являются статическими файлами, хранящимися в файловой системе.

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

project root
├── server.js
├── package.json 
└── public
    ├── index.html
    └── script.js

Вот как настроить Express для обслуживания статических файлов:

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

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

Примечание: как только папка настроена, index.html, script.js и все файлы в «общедоступной» папке будут доступны на корневом пути (вы не должны указывать /public/ в URL-адресе). Это связано с тем, что экспресс ищет файлы, относящиеся к установленной статической папке. Вы можете указать префикс виртуального пути, как показано ниже:

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

сделает ресурсы доступными в /static/ prefix.

Несколько папок

Одновременно можно определить несколько папок:

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

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

Именованные маршруты в стиле Django

Одна из больших проблем заключается в том, что ценные именованные маршруты не поддерживаются Express из коробки. Решение заключается в установке поддерживаемого стороннего пакета, например express-reverse :

npm install express-reverse

Подключите его в свой проект:

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

Затем используйте его так:

app.get('test', '/hello', function(req, res) {
  res.end('hello');
});

Недостатком этого подхода является то , что вы не можете использовать route модуль Express , как показано в Advanced использования маршрутизатора . Обходным путем является передача вашего app в качестве параметра для вашего маршрутизатора:

require('./middlewares/routing')(app);

И используйте его как:

module.exports = (app) => {
    app.get('test', '/hello', function(req, res) {
      res.end('hello');
    });
};

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

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

Основная обработка ошибок

По умолчанию Express будет искать представление «error» в каталоге /views для рендеринга. Просто создайте представление «ошибка» и поместите его в каталог представлений для обработки ошибок. Ошибки записываются с сообщением об ошибке, статусом и трассировкой стека, например:

просмотров / error.pug

html
  body
      h1= message
      h2= error.status
      p= error.stack

Расширенная обработка ошибок

Определите функции промежуточного программного обеспечения обработки ошибок в самом конце стека функций промежуточного программного обеспечения. У них есть четыре аргумента вместо трех (err, req, res, next) :

app.js

// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;

    //pass error to the next matching route.
    next(err);
});

// handle error, print stacktrace
app.use(function(err, req, res, next) {
    res.status(err.status || 500);

    res.render('error', {
        message: err.message,
        error: err
    });
});

Вы можете определить несколько функций промежуточного программного обеспечения обработки ошибок, как и обычные функции промежуточного программного обеспечения.

Использование промежуточного программного обеспечения и следующего обратного вызова

Express передает next обратный вызов каждому обработчику маршрута и функции промежуточного программного обеспечения, которые могут использоваться для разрыва логики для отдельных маршрутов через несколько обработчиков. Вызов next() без аргументов говорит express для продолжения следующего соответствующего промежуточного программного обеспечения или обработчика маршрута. Вызов next(err) с ошибкой вызовет любое промежуточное программное обеспечение обработчика ошибок. Вызов next('route') будет обходить любое последующее промежуточное ПО на текущем маршруте и перейти к следующему согласованному маршруту. Это позволяет разделить логику домена на повторно используемые компоненты, которые являются автономными, более простыми для тестирования и проще поддерживать и изменять.

Несколько совпадающих маршрутов

Запросы в /api/foo или to /api/bar будут запускать начальный обработчик для поиска члена, а затем передать управление фактическому обработчику для каждого маршрута.

app.get('/api', function(req, res, next) {
  // Both /api/foo and /api/bar will run this
  lookupMember(function(err, member) {
    if (err) return next(err);
    req.member = member;
    next();
  });
});

app.get('/api/foo', function(req, res, next) {
  // Only /api/foo will run this
  doSomethingWithMember(req.member);
});

app.get('/api/bar', function(req, res, next) {
  // Only /api/bar will run this
  doSomethingDifferentWithMember(req.member);
});

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

Обработчики ошибок являются промежуточным программным обеспечением с function(err, req, res, next) подписи function(err, req, res, next) . Их можно настроить на один маршрут (например, app.get('/foo', function(err, req, res, next) ), но, как правило, достаточно одного обработчика ошибок, который отображает страницу с ошибкой.

app.get('/foo', function(req, res, next) {
  doSomethingAsync(function(err, data) {
    if (err) return next(err);
    renderPage(data);
  });
});

// In the case that doSomethingAsync return an error, this special
// error handler middleware will be called with the error as the 
// first parameter.
app.use(function(err, req, res, next) {
  renderErrorPage(err);
});

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

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

app.get('/bananas', function(req, res, next) {
  getMember(function(err, member) {
    if (err) return next(err);
    // If there's no member, don't try to look
    // up data. Just go render the page now.
    if (!member) return next('route');
    // Otherwise, call the next middleware and fetch
    // the member's data.
    req.member = member;
    next();
  });
}, function(req, res, next) {
  getMemberData(req.member, function(err, data) {
    if (err) return next(err);
    // If this member has no data, don't bother
    // parsing it. Just go render the page now.
    if (!data) return next('route');
    // Otherwise, call the next middleware and parse
    // the member's data. THEN render the page.
    req.member.data = data;
    next();
  });
}, function(req, res, next) {
  req.member.parsedData = parseMemberData(req.member.data);
  next();
});

app.get('/bananas', function(req, res, next) {
  renderBananas(req.member);
});

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

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

Основные документы можно найти здесь

app.get('/path/:id(\\d+)', function (req, res, next) { // please note: "next" is passed
    if (req.params.id == 0) // validate param
        return next(new Error('Id is 0')); // go to first Error handler, see below

    // Catch error on sync operation
    var data;
    try {
        data = JSON.parse('/file.json');
    } catch (err) {
        return next(err);
    }

    // If some critical error then stop application
    if (!data)
        throw new Error('Smth wrong');

    // If you need send extra info to Error handler
    // then send custom error (see Appendix B)
    if (smth)
        next(new MyError('smth wrong', arg1, arg2))

    // Finish request by res.render or res.end
    res.status(200).end('OK');
});    

// Be sure: order of app.use have matter
// Error handler
app.use(function(err, req, res, next)) {
    if (smth-check, e.g. req.url != 'POST') 
        return next(err); // go-to Error handler 2.

    console.log(req.url, err.message);

    if (req.xhr) // if req via ajax then send json else render error-page
        res.json(err);
    else 
        res.render('error.html', {error: err.message});  
});

// Error handler 2
app.use(function(err, req, res, next)) {
    // do smth here e.g. check that error is MyError
    if (err instanceof MyError) {
        console.log(err.message, err.arg1, err.arg2);
    }     
    ...
    res.end();
});

Приложение

// "In Express, 404 responses are not the result of an error, 
// so the error-handler middleware will not capture them." 
// You can change it.
app.use(function(req, res, next) {
    next(new Error(404)); 
});

Приложение B

// How to define custom error
var util = require('util');
...
function MyError(message, arg1, arg2) {
    this.message = message;
    this.arg1 = arg1;
    this.arg2 = arg2;
    Error.captureStackTrace(this, MyError);
}
util.inherits(MyError, Error);
MyError.prototype.name = 'MyError';

Крюк: как выполнить код перед любым req и после любого res

app.use() и промежуточное ПО можно использовать для «раньше», а комбинацию событий закрытия и завершения можно использовать для «после».

app.use(function (req, res, next) {
    function afterResponse() {
        res.removeListener('finish', afterResponse);
        res.removeListener('close', afterResponse);

        // actions after response
    }
    res.on('finish', afterResponse);
    res.on('close', afterResponse);

    // action before request
    // eventually calling `next()`
    next();
});
...
app.use(app.router);

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

Просто убедитесь, что это «промежуточное программное обеспечение» используется до приложения app.router поскольку порядок имеет значение.


Оригинальный пост здесь

Обработка запросов POST

Так же, как вы обрабатываете запросы на получение в Express с помощью метода app.get, вы можете использовать метод app.post для обработки почтовых запросов.

Но прежде чем вы сможете обрабатывать запросы POST, вам нужно будет использовать промежуточное программное обеспечение body-parser . Он просто анализирует тело POST , PUT , DELETE и других запросов.

Body-Parser ПО Body-Parser анализирует тело запроса и превращает его в объект, доступный в req.body

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

const express = require('express');

const app = express();

// Parses the body for POST, PUT, DELETE, etc.
app.use(bodyParser.json());

app.use(bodyParser.urlencoded({ extended: true }));

app.post('/post-data-here', function(req, res, next){

    console.log(req.body); // req.body contains the parsed body of the request.

});

app.listen(8080, 'localhost');

Ниже приведен пример установки и чтения файлов cookie с использованием модуля cookie-parser :

var express = require('express');
var cookieParser = require('cookie-parser'); // module for parsing cookies
var app = express();
app.use(cookieParser());

app.get('/setcookie', function(req, res){
    // setting cookies
    res.cookie('username', 'john doe', { maxAge: 900000, httpOnly: true });
    return res.send('Cookie has been set');
});

app.get('/getcookie', function(req, res) {
    var username = req.cookies['username'];
    if (username) {
        return res.send(username);        
    }

    return res.send('No cookie found');
});

app.listen(3000);

Пользовательское промежуточное ПО в Express

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

app.use(function(req, res, next){ });    // signature

пример

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

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

//each request will pass through it
app.use(function(req, res, next){
    req.user = 'testuser';
    next();    // it will pass the control to next matching route
});

app.get('/', function(req, res){
    var user = req.user;
    console.log(user); // testuser
    return res.send(user);
});

app.listen(3000);

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

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

пример

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

//GET /names/john
app.get('/names/:name', function(req, res, next){
    if (req.params.name == 'john'){
        return res.send('Valid Name');
    } else{
        next(new Error('Not valid name'));    //pass to error handler
    }
});

//error handler
app.use(function(err, req, res, next){
    console.log(err.stack);    // e.g., Not valid name
    return res.status(500).send('Internal Server Occured');
});

app.listen(3000);

Добавление промежуточного ПО

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

Функции промежуточного программного обеспечения могут выполнять любой код, вносить изменения в объекты res и req , завершать цикл ответа и вызывать следующее промежуточное программное обеспечение.

Очень распространенным примером промежуточного программного обеспечения является модуль cors . Чтобы добавить поддержку CORS, просто установите ее, установите ее и поместите эту строку:

app.use(cors());

перед любыми маршрутизаторами или функциями маршрутизации.

Привет, мир

Здесь мы создаем базовый сервер приветствия с помощью Express. Маршруты:

  • '/'
  • «/ Вики»

А для отдыха даст «404», т.е. страница не найдена.

'use strict';

const port = process.env.PORT || 3000;

var app = require('express')();
    app.listen(port);

app.get('/',(req,res)=>res.send('HelloWorld!'));
app.get('/wiki',(req,res)=>res.send('This is wiki page.'));
app.use((req,res)=>res.send('404-PageNotFound'));

Примечание. Мы поместили маршрут 404 в качестве последнего маршрута в качестве экспресс-стеков в порядке и обрабатываем их для каждого запроса последовательно.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow