我有这个问题,在路由器文件中返回一个路由器对象 - 中间件在响应已经被调用后被调用.
我认为在路线之后放置的中间件永远不会为该路线执行,我特别认为如果已经给出了响应,那将是真的.
主要问题:
中间件应该在响应后停止被调用吗?
例如:当调用端点"/ login"并发送响应时,调用中间件A和B.
注意:我已经将路由器包装在一个更高阶的函数中(对于socket.io功能,但这不是重点).
代码示例:
var express = require('express');
var router = express.Router();
var wrappedRouter = function(val) {
router.get('/login', function(req, res) {
console.log("Inside login route");
res.sendFile(path.resolve('login.html'))
}
router.use(function(req, res, next) {
console.log("Exectuing middleware A");
});
router.use(function(req, res, next) {
console.log("Exectuing middleware B");
});
router.get('/another-route', function(req, res) {
res.sendFile(path.resolve('login.html'))
}
return router;
}
//Prints:
// Inside login route
// Exectuing middleware A
// Exectuing middleware B
Run Code Online (Sandbox Code Playgroud)
你的假设是绝对正确的,如果你不打电话给下一个,链中的下一个中间件永远不会被执行,你面临的问题是,因为你已经猜到,由于你的页面正在请求的静态资源,如favicon或图像或其他任何事情(单独请求).要获得具体证据,您可以在提供快速请求时记录URL,并查看请求的内容以及执行的内容req.url,如下所示
var express = require('express');
var router = express.Router();
var path = require('path');
var wrappedRouter = function(val) {
router.get('/login', function(req, res) {
console.log("Inside login route: " + req.url);
res.sendFile(path.resolve('login.html'))
});
router.use(function(req, res, next) {
console.log("Exectuing middleware A: " + req.url);
});
router.use(function(req, res, next) {
console.log("Exectuing middleware B: " + req.url);
});
router.get('/another-route', function(req, res) {
res.sendFile(path.resolve('login.html'))
});
return router;
}
module.exports = wrappedRouter({});
Run Code Online (Sandbox Code Playgroud)
请注意req.url,console.log("Inside login route: " + req.url);这将附加当前的req资源,我们将能够识别所调用的内容和原因.如下所示

所以现在我们知道发生了什么以及为什么,现在让我们看看我们如何解决它.
在表达我们注册表达app的东西的顺序非常重要.我建议单独注册您的中间件(第一个),然后注册您的路由,这将增加您超级棒代码的可管理性!
话虽如此,随着时间的推移出现问题,顺序很重要,在你的情况下发生了什么,表达顺序尝试每个中间件,直到它用完为止.因此,当服务器请求'favicon'(或其他一些静态资源)时,它会开始按顺序执行匹配的中间件."中间件A"处理请求并生成输出(请记住,不提供favicon,实际上没有任何操作,请求将继续处理,直到您下一次呼叫或发送响应内容.
问题的解决方案是在注册任何内容之前在app.js的开头注册一个静态文件夹.这样,当请求静态资源时,它们立即被提供,而静态资源中间件不能接受的其他请求将被传递到您的中间件.
不建议您提供服务文件,因为随着应用程序的增长,您可能会觉得难以管理,而应该使用视图引擎/静态中间件来获得您想要实现的目标,如下面的代码所示.
您的应用结构应如下所示,它将解决您的问题.
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//This will return wrapped routers
var routes = require('./routes/index');
var other = require('./routes/other');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
//Just after registering all request parsing middleware, register static middleware
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/others', other);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Run Code Online (Sandbox Code Playgroud)
如果你是新手表达并想要开始并看看它是如何工作的,我写了一篇关于它的小博客,第一部分已经完成,其余的都在排队;)
开始使用Express并构建RESTful api 在这一部分中,我将展示如何构建一个快速应用程序,代码来自它.你可能会发现它很有帮助.
希望能帮助到你!如果您还有其他需要,请告诉我!
| 归档时间: |
|
| 查看次数: |
2141 次 |
| 最近记录: |