当前位置: 首页 > 知识库问答 >
问题:

节点。js/Express。js-应用程序是如何运行的。路由器工作?

卜昂熙
2023-03-14

在我询问应用程序之前。路由器我想我至少应该解释一下我认为在使用中间件时会发生什么。要使用中间件,要使用的函数是app。使用()。当执行中间件时,它将使用next()调用下一个中间件,或者使其不再被调用。这意味着我放置中间件调用的顺序很重要,因为一些中间件依赖于其他中间件,而靠近末尾的一些中间件甚至可能不会被调用。

今天我正在开发我的应用程序,让我的服务器在后台运行。我想做一些更改,刷新我的页面,并立即看到更改。具体地说,我正在修改我的布局。我无法让它工作,所以我搜索了堆栈

当我快递的时候。js应用程序(3.0.0rc4版),我在我的应用程序中使用了命令express-app--sessions--css-stylus。js文件代码是随我的应用程序安装的。路由器位于快车上方。static()需要('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()是我信息的缓存,如果应用程序找不到请求的页面,它会检查缓存,看看它是否存在。


共有3个答案

干旺
2023-03-14

在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!'));

route.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;

服务器中。js我们导入了路由的路由器对象。js文件,并以以下方式在服务器中应用它。js

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

现在查看路线中的所有路线。js具有以下基本URL:

http://localhost:3000/route

采用这种方法的主要优点是,现在我们的应用程序更加模块化。现在,某个路由的所有路由处理程序都可以放入不同的文件中,这使得所有内容都更易于维护和查找。

舒博雅
2023-03-14

路由意味着确定应用程序如何响应特定endpoint的客户端请求,该endpoint是URI(或路径)和特定HTTP请求方法(GET、POST等)。每个路由可以有一个或多个处理程序函数,这些函数在路由匹配时执行。

在Express 4.0路由器中,我们在定义路由方面比以往任何时候都更具灵活性。

表达。路由器()被多次使用来定义路由组。

用作处理请求的中间件的路由。

作为中间件使用“.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')
})
董砚
2023-03-14

注意:这描述了Express在版本2和3中的工作方式。有关Express 4的信息,请参阅本文末尾。

静态只服务于磁盘中的文件(静态资源)。您给它一个路径(有时称为挂载点),它为该文件夹中的文件提供服务。

例如,express.static('/var/www')将为该文件夹中的文件提供服务。因此,向Node服务器请求超文本传输协议://server/file.html将服务于/var/www/file.html

路由器是运行路由的代码。当你使用应用程序时。get('/user',函数(req,res){…}),实际上是路由器调用回调函数来处理请求。

将内容传递给应用程序的顺序。use确定每个中间件处理请求的顺序。例如,如果您有一个名为test的文件。html在静态文件夹和路由中:

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

哪一个被发送到请求http://server/test.html?无论哪个中间件被赋予优先使用

如果你这样做:

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

然后磁盘上的文件被送达。

如果你用另一种方式做,

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

然后路由处理程序获取请求,并将“Hello from route handler”发送到浏览器。

通常,您希望将路由器置于静态中间件之上,以便意外命名的文件不能覆盖其中一条路由。

请注意,如果您没有显式地使用路由器,它将由Express在您定义路由时隐式添加(这就是为什么即使您注释掉app.use(app.router),您的路由仍然有效)。

一位评论者提出了另一个我没有提到的关于静态路由器顺序的观点:对应用程序整体性能的影响。

静态上面使用路由器的另一个原因是优化性能。如果您先放置静态,则每次请求时都会点击硬盘,查看文件是否存在。在一个快速测试中,我发现在一个卸载的服务器上,这个开销达到了~1ms。(在负载情况下,这个数字很可能会更高,因为在负载情况下,请求将争夺磁盘访问权。)

使用路由器首先,匹配路由的请求不必命中磁盘,从而节省宝贵的毫秒。

当然,有一些方法可以减轻静态的开销。

最好的选择是将所有静态资源放在特定的文件夹下。然后,您可以将静态加载到该路径,以便它仅在路径以以下方式开始时运行:

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

在这种情况下,您应该将其放在路由器上方。如果存在文件,这可以避免处理其他中间件/路由器,但老实说,我怀疑您是否能获得这么多。

您还可以使用static Cache,它将静态资源缓存在内存中,这样您就不必为通常请求的文件命中磁盘。(警告:静态缓存显然将在未来被删除。)

但是,我认为staticCache不会缓存否定的答案(当文件不存在时),因此,如果您将staticCache放在router上方,而不将其装入路径,则不会有任何帮助。

与所有关于性能的问题一样,测量并基准测试您的真实世界应用程序(负载下),以了解瓶颈真正在哪里。

Express 4.0删除app.router。所有中间件(app.use)和路由(app.get等)现在都按照它们添加的顺序进行精确处理。

换言之:

所有路由方法都将按其出现的顺序添加。你不应该做app。使用(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中更改的更多信息。

 类似资料:
  • 我手动添加了一个config,但是VS code也显示了另一个。两者都执行应用程序,但当我运行我的应用程序时,它不会在终端中显示所有的应用程序控制台输出,例如错误、日志等。但当我运行VS Code的应用程序时,一切都很好,我更喜欢在整个团队中使用该配置。 问题是我无法签入配置,所以在另一台机器上它不会按预期显示。VS代码如何获得配置并执行它?如果我可以在我的配置中复制它,那么我可以在我的回购协议中

  • 我的导航不工作,因为某些原因,我有另一个应用程序运行良好,但这一个不能找到错误,请帮助 反应路由器不工作。反应JS 我需要你的帮助。 使用react-router,我可以使用Link元素创建由react router本地处理的链接。

  • 我有一些下面这样的代理代码。问题是,每当目标服务器停机时,此代码都无法捕获错误,导致整个应用程序崩溃,出现。 对于代理服务器来说,这很糟糕,它只需要向调用者返回一个错误,而不是在第一次无法访问目标服务器时完全崩溃。 现在什么是正确的方法? 节点版本6。 谢谢!

  • 问题内容: 因此,我开始使用Node.js。我在Nodejs.org上与Ryan Dahl一起观看了视频,听说他向网站推荐了Express-js。 我下载了最新版本的Express,并开始编写代码。我在/上有一个完整的静态视图,但是一旦尝试发送参数,就会收到如下错误: 我尝试按照expressjs.com上的指南进行操作,但是在最新版本中,使用路由的方式已更改,这使该指南无法使用。 指南: 由Ex

  • 目前,我正面临一个技术决策,我个人无法找到解决方案。 我目前正在开发一个多租户数据库。 结构如下: 有一个核心数据库,用于保存特定租户的数据和关系 有多个租户数据库实例(通过核心数据库中的查询,可以确定我应该连接到哪个租户id) 每个租户都位于一个单独的数据库实例(位于单独的服务器上) 每个租户都有特定的数据,其他租户都不应访问这些数据 每个数据库最好是mySQL(但如果有更好的选择,我愿意接受建