在我询问之前,app.router我认为我至少应该解释一下我认为在使用中间件时会发生什么。要使用中间件,要使用的功能是app.use(). 当中间件被执行时,它要么通过 using 调用下一个中间件,要么通过next()make 它不再调用中间件。这意味着我放置中间件调用的顺序很重要,因为一些中间件依赖于其他中间件,而靠近末尾的一些中间件甚至可能不会被调用。
app.router
app.use()
next()
今天我正在处理我的应用程序,并让我的服务器在后台运行。我想进行一些更改并刷新我的页面并立即查看更改。具体来说,我正在更改我的布局。。它说要确保express.static()在下面require('stylus')。但是当我查看那个 OP的代码时,我看到他app.router在中间件调用的最后进行了调用,我试图弄清楚为什么会这样。
express.static()
require('stylus')
当我创建我的 Express.js 应用程序(版本 3.0.0rc4)时,我使用了命令express app --sessions --css stylus,并且在我的 app.js 文件中,代码与我app.router上面的express.static()和require('stylus')调用一起设置。所以看起来,如果它已经以这种方式设置,那么它应该保持这种方式。
express app --sessions --css 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它并在屏幕上显示测试。哈哈,好吧,我不知道是什么app.router。无论它是否包含在我的代码中,我的路由都很好。所以我肯定错过了一些东西。
/
/test
所以这是我的问题:
有人可以解释一下app.router它的作用,它的重要性,以及我应该将它放在我的中间件调用中的什么位置吗?如果我能得到一个关于express.static(). 据我所知,express.static()是我的信息的缓存,如果应用程序找不到请求的页面,它会检查缓存是否存在。
注意: 这描述了 Express 在版本 2 和 3 中的工作方式。有关 Express 4 的信息,请参阅本文末尾。
static只是从磁盘提供文件( 静态 资源)。您给它一个路径(有时称为挂载点),它会为该文件夹中的文件提供服务。
static
例如,express.static('/var/www')将提供该文件夹中的文件。因此,对您的节点服务器的请求http://server/file.html将服务/var/www/file.html。
express.static('/var/www')
http://server/file.html
/var/www/file.html
router是运行您的路线的代码。当你这样做时app.get('/user', function(req, res) { ... });,它router实际上是调用回调函数来处理请求。
router
app.get('/user', function(req, res) { ... });
您传递事物app.use的顺序决定了每个中间件有机会处理请求的顺序。例如,如果您test.html在静态文件夹中调用了一个文件和一个路由:
app.use
test.html
app.get('/test.html', function(req, res) { res.send('Hello from route handler'); });
哪一个被发送给请求的客户http://server/test.html?先给哪个中间件use。
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”发送到浏览器。
通常,您希望将路由器 放在 静态中间件之上,以便意外命名的文件无法覆盖您的路由之一。
请注意,如果您没有明确地use,router它会在您定义路由时由 Express 隐式添加(这就是即使您注释掉了您的路由仍然有效的原因app.use(app.router))。
app.use(app.router)
一位评论者提出了关于顺序的另一点static,router但我没有解决:对应用程序整体性能的影响。
use router上面的另一个原因static是优化性能。如果您static放在第一位,那么您将在每个请求上点击硬盘驱动器以查看文件是否存在。在快速测试中,我发现在未加载的服务器上,此开销总计约为 1 毫秒。(这个数字在负载下很可能会更高,因为请求将竞争磁盘访问。)
router首先,匹配路由的请求永远不必访问磁盘,从而节省宝贵的毫秒数。
当然,有一些方法可以减轻static‘s 的开销。
最好的选择是将所有静态资源放在特定文件夹下。(IE /static)然后您可以挂载static到该路径,以便它仅在路径以以下开头时运行/static:
/static
app.use('/static', express.static(__dirname + '/static'));
在这种情况下,你可以把它放在上面router。如果文件存在,这可以避免处理其他中间件/路由器,但老实说,我怀疑你会获得那么多。
您还可以使用staticCache,它将静态资源缓存在内存中,这样您就不必为经常请求的文件而访问磁盘。( 警告: staticCache 将来显然会被删除。)
staticCache
但是,我认为不会staticCache缓存否定答案(当文件不存在时),因此如果您在没有将其安装到路径的情况下将其放在staticCache上面并没有帮助。router
与所有有关性能的问题一样, 测量和基准测试您的实际应用程序 (在负载下)以查看瓶颈的真正位置。
Express 4.0 删除了 app.router. 现在,所有中间件 ( app.use) 和路由 ( app.getet al) 都按照它们添加的顺序进行处理。
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);
所有路由方法都将按照它们出现的顺序添加。你不应该 这样 做app.use(app.router)。这消除了 Express 最常见的问题。
换句话说,混合app.use()和app[VERB]()将 完全 按照它们被调用的顺序工作。
app[VERB]()
app.get('/', home); app.use('/public', require('st')(process.cwd())); app.get('/users', users.list); app.post('/users', users.create);
阅读有关 Express 4 更改的更多信息。