路由后的 Node Express 4 中间件
Posted
技术标签:
【中文标题】路由后的 Node Express 4 中间件【英文标题】:Node Express 4 middleware after routes 【发布时间】:2014-08-07 04:03:16 【问题描述】:在升级到 Express 4 并删除 app.router 之后,我正在努力让中间件在路由执行后执行。
例如以下代码正确响应“hello”,但从不调用配置的中间件
var express = require( "express" )();
express.get( "/", function( req, res )
res.send( "hello" );
);
express.use( function( req, res, next )
console.log( "world" );
next();
);
express.listen( 8888 );
澄清:
以下代码在控制台上显示“之前”,而不是“之后”:
var express = require( "express" )();
express.use( function( req, res, next )
console.log( "before" );
next();
);
express.get( "/", function( req, res )
res.send( "hello" );
);
express.use( function( req, res, next )
console.log( "after" );
next();
);
express.listen( 8888 );
【问题讨论】:
为我工作。什么不适合你。 我从来没有看到 console.log 输出 在 node.js 命令行中为我显示。你有额外的代码吗? 不,就是这样。你运行的是什么版本的快递? (我在 4.4) 我的是 4.4.3。试试看。 【参考方案1】:顺序很重要http://expressjs.com/4x/api.html#app.use
express.use( function( req, res, next )
console.log( "world" );
next();
);
express.get( "/", function( req, res )
res.send( "hello" );
);
【讨论】:
是的,但这是错误的顺序。我希望我的中间件在路由处理程序之后执行。【参考方案2】:您是否检查过将您的 console.log 放在 next() 调用之后?
express.use( function( req, res, next )
next();
console.log( "world" );
);
express.get( "/", function( req, res )
res.send( "hello" );
);
【讨论】:
它看起来像一个健壮的变种。 如果请求执行任何异步操作,这将无法正常工作【参考方案3】:关于 Express 4,第二个示例中的“after”函数永远不会被调用,因为中间函数永远不会调用 next()。
如果您希望调用“after”函数,则需要从中间函数添加并调用下一个回调,如下所示:
var express = require( "express" )();
express.use( function( req, res, next )
console.log( "before" );
next();
);
express.get( "/", function( req, res, next )
res.send( "hello" );
next(); // <=== call next for following middleware
);
express.use( function( req, res, next )
console.log( "after" );
next();
);
express.listen( 8888 );
res.send()
将标头和响应写回客户端。
请注意,一旦调用了res.send()
,您就不想更新响应标头或内容。但是您可以执行其他任务,例如数据库更新或日志记录。
请注意,express 查看中间件函数中参数的数量并执行不同的逻辑。以express error handlers为例,它定义了4个参数。
表达错误处理程序签名:
app.use(function(err, req, res, next) );
对中间件链中的最后一项调用 next 是可选的,但如果你改变了事情,这可能是一个好主意。
【讨论】:
现在是真的。大多数 express 示例的路由在处理函数中指定为 2。但是这样做会阻止添加应该在处理路由后执行的中间件。这对他们来说似乎是一个奇怪的约定。【参考方案4】:正确答案是使用res.on("finish", cb)
回调。
即:
express.use(function(req, res, next)
console.log("before");
res.on("finish", function()
console.log("after");
);
next();
);
【讨论】:
这家伙说的是“res.once”,而不是“res.on”lunchbadger.com/… @datdinhquoc 这并不重要,因为在 Express 处理完响应对象后res
将不可用,因为每个请求都会导致新的 req
和 res
对创建(由 Express)。你是对的,通常负责任的开发人员应该做的,但在这种特殊情况下,它们是相同的。
@Catfish 这是使用节点的http
模块response
功能node docs。正如您将在express docs 中看到的,express 的“res 对象是 Node 自己的响应对象的增强版本,支持所有内置字段和方法。”
这种方法适用于人们已经制作了一个 API 而没有在所有路由中使用 next
的情况。【参考方案5】:
可以在不同的js文件中使用Middle ware函数,也可以使用require函数。以便在 http 请求之前和之后调用它。
index.js:
const logger = require("./logger");
const express = require("express");
var app = express();
app.listen("3000",()=>console.log("listening on 3000..."))
app.use(logger("AppServer"));
//get expression
app.get("/", function(req,res)
console.log("res not received");
res.send("Hello World");
console.log("res received");
)
logger.js
module.exports = (applicationName) =>
return function log(req,res,next)
console.log(applicationName+" started "+os.hostname);
res.on("finish",()=>
console.log(applicationName+" completed "+os.hostname);
)
next();
;
output:
AppServer started hostname-PC
res not received
res received
AppServer completed hostname-PC
注意:在logger.js中不要使用res.on("finish",callback),可以使用req.on("end",callback)
【讨论】:
以上是关于路由后的 Node Express 4 中间件的主要内容,如果未能解决你的问题,请参考以下文章
Node/Express 的 Passport 身份验证中间件 - 如何保护所有路由