Узел.js / Express.js-как работает приложение.маршрутизатор работает?

прежде чем я спрошу о app.router Я думаю, что должен объяснить, по крайней мере, то, что я думаю, происходит при работе с middleware. Для использования промежуточного ПО используется функция app.use(). Когда промежуточное ПО выполняется, оно либо вызовет следующее промежуточное ПО с помощью next() или сделать так, чтобы больше не вызывалось промежуточное ПО. Это означает, что порядок, в котором я размещаю вызовы промежуточного программного обеспечения, важен, потому что некоторые промежуточные программы зависят от других промежуточных программ, а некоторые промежуточные программы в конце могут даже не быть призванным.

сегодня я работал над своим приложением и мой сервер работал в фоновом режиме. Я хотел внести некоторые изменения и обновить свою страницу и сразу увидеть изменения. В частности, я вносил изменения в макет. Я не мог заставить его работать, поэтому я искал переполнение стека для ответа и нашел этот вопрос. Он говорит, чтобы убедиться, что express.static() под require('stylus'). Но когда я смотрел на код этой операции, я увидел, что у него есть его app.router звонок очень конец его промежуточных вызовов, и я попытался понять, почему это было.

когда я сделал свой экспресс.приложение js (версия 3.0.0rc4), я использовал команду express app --sessions --css stylus и в мое приложение.JS-файл код пришел с настройкой my app.router выше express.static() и require('stylus') звонки. Поэтому кажется, что если он уже настроен таким образом, то он должен оставаться таким.

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

app.configure(function(){
  //app.set() calls
  //app.use() calls
  //...
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});

app.get('/', routes.index);

app.get('/test', function(req, res){
  res.send('Test');
});

так Я решил, что первым шагом будет выяснить, почему важно даже иметь app.router в моем коде. Поэтому я прокомментировал это, запустил свое приложение и перешел к /. Он прекрасно отображал мою индексную страницу. Хм, может быть, это сработало, потому что я экспортировал маршрутизацию из своего файла маршрутов (routes.индекс.) Затем я перешел к /test и он отобразил тест на экране. Ха-ха, хорошо, я понятия не имею, что app.router делает. Включен ли он в мой код или нет, моя маршрутизация в порядке. Так что я определенно чего-то не хватает.

Итак, Вот Мой Вопрос:

может кто-нибудь объяснить, что app.router делает, важность этого, и где я должен поместить его в мои вызовы middleware? Было бы также неплохо, если бы я получил краткое объяснение о express.static(). Насколько я могу судить, express.static() - это кэш моей информации, и если приложение не может найти запрошенную страницу, оно проверит кэш, чтобы увидеть, существует ли он.

3 ответов


Примечание: это описывает, как Express работал в версиях 2 и 3. См. конец этого сообщения для получения информации о Express 4.


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

например, express.static('/var/www') будет обслуживать файлы в этой папке. Итак, запрос на ваш сервер узлов для http://server/file.html будет служить /var/www/file.html.

router - это код, который запускает свои маршруты. Когда вы делаете app.get('/user', function(req, res) { ... });, это router это фактически вызывает функцию обратного вызова для обработки запроса.

порядок, который вы передаете вещи app.use определяет порядок, в котором каждому промежуточному по предоставляется возможность обработки запроса. Например, если у вас есть файл с именем test.html в вашей статической папке и маршруте:

app.get('/test.html', function(req, res) {
    res.send('Hello from route handler');
});

какой из них отправляется клиенту с запросом http://server/test.html? Какое бы промежуточное ПО ни было дано use первый.

если вы сделаете это:

app.use(express.static(__dirname + '/public'));
app.use(app.router);

затем файл на диск подается.

если вы сделаете это по-другому,

app.use(app.router);
app.use(express.static(__dirname + '/public'));

затем обработчик маршрута получает запрос, и" привет от обработчика маршрута " отправляется в браузер.

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

обратите внимание, что если вы явно не use на router, он неявно добавляется Express в точке, где вы определяете маршрут (именно поэтому ваши маршруты все еще работали, хотя вы прокомментировали app.use(app.router)).


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

другая причина use router выше static для оптимизации производительности. Если поставить static во-первых, затем вы нажмете жесткий диск на каждый запрос, чтобы увидеть, существует ли файл. В быстрый тест, я обнаружил, что эти накладные расходы составили ~1 мс на выгруженном сервере. (Это число, скорее всего, будет выше при загрузке, где запросы будут конкурировать за доступ к диску.)

С router во-первых, запрос, соответствующий маршруту, никогда не должен попасть на диск, экономя драгоценные миллисекунды.

конечно, есть способы, чтобы смягчить staticС НАКЛАДНЫМИ.

лучший вариант-поместить все ваши статические ресурсы в определенную папку. (IE /static), то вы можете установить static к этому пути, так что он запускается только тогда, когда путь начинается с /static:

app.use('/static', express.static(__dirname + '/static'));

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

вы также можете использовать staticCache, который кэширует статические ресурсы в памяти, так что вам не нужно нажимать на диск для обычно запрашиваемых файлов. (предупреждение: staticCache видимо быть удалены в будущем.)

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

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


Экспресс-4

Экспресс 4.0 выводит app.router. Все промежуточное ПО (app.use) и маршруты (app.get et al) теперь обрабатываются точно в том порядке, в котором они добавляются.

другими словами:

все методы маршрутизации будут добавлены в том порядке, в котором они появляются. Вы должны не do app.use(app.router). Это устраняет наиболее распространенную проблему с Express.

другими словами, смешивая app.use() и app[VERB]() совместимость ровно в том порядке, в котором они вызываются.

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

подробнее об изменениях в Express 4.


маршрутизация означает определение того, как приложение отвечает на запрос клиента к определенной конечной точке, которая является URI (или путем) и определенным методом HTTP-запроса (GET, POST и т. д.). Каждый маршрут может иметь одну или несколько функций обработчика, которые выполняются при сопоставлении маршрута.

в маршрутизаторе Express 4.0 нам предоставляется больше гибкости, чем когда-либо прежде, в определении наших маршрутов.

экспресс.Router () используется несколько раз для определения группы маршрутов.

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

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

app.route () используется как ярлык маршрутизатора для определения нескольких запросов на маршруте

когда мы, используя приложение.route (), мы прикрепляем наше приложение с этим маршрутизатором.

var express = require('express'); //used as middleware
var app = express(); //instance of express.
app.use(app.router);
app.use(express.static(__dirname + '/public')); //All Static like [css,js,images] files are coming from public folder
app.set('views',__dirname + '/views'); //To set Views
app.set('view engine', 'ejs'); //sets View-Engine as ejs
app.engine('html', require('ejs').renderFile); //actually rendering HTML files through EJS. 
app.get('/', function (req, res) {
  res.render('index');  
})
app.get('/test', function (req, res) {
  res.send('test')
})

в Express версии 4, мы можем легко определить маршруты следующим образом:

сервер.js:

const express = require('express');
const app = express();
const route = require('./route');

app.use('/route', route);
// here we pass in the imported route object

app.listen(3000, () => console.log('Example app listening on port 3000!'));

маршрут.js:

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

router.get('/specialRoute', function (req, res, next) {
     // route is now http://localhost:3000/route/specialRoute
});

router.get('/', function (req, res, next) {
    // route is now http://localhost:3000/route
});

module.exports = router;

на server.js мы импортировали объект маршрутизатора route.js файл и применить его следующим образом в server.js:

app.use('/route', route);

теперь все маршруты в route.js имеются следующие основания URL-адрес:

http://localhost:3000/route

почему такой подход:

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