Узел.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);
маршрутизация означает определение того, как приложение отвечает на запрос клиента к определенной конечной точке, которая является 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-адрес:
почему такой подход:
основным преимуществом такого подхода является то, что теперь наше приложение больше модульная. Все обработчики маршрутов для определенного маршрута теперь можно поместить в разные файлы, что делает все более доступным и простым в поиске.