Node.js/Express.js - Как работает app.router?

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

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

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

После повторной настройки моего кода, чтобы я мог видеть мои изменения в 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.index). Итак, я перешел к /test, и он отобразил Test на экране. Ха-ха, хорошо, я понятия не имею, что делает app.router. Включен ли он в мой код или нет, моя маршрутизация в порядке. Поэтому я определенно что-то пропустил.

Итак, вот мой вопрос:

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

Ответ 1

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


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

Например, express.static('/var/www') будет обслуживать файлы в этой папке. Таким образом, запрос на ваш сервер Node для 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'));

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

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

Обратите внимание, что если вы явно не указали 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, не устанавливая его в путь.

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


Экспресс 4

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

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

Все методы маршрутизации будут добавлены в том порядке, в котором они отображаются. Вы должны не делать 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.

Ответ 2

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

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

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

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

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

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

когда мы используем app.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')
})