我看到的几乎每个Express应用程序都有app.use
关于中间件的声明,但是我没有找到关于中间件实际上是什么以及该app.use
声明在做什么的清晰,简洁的解释。甚至快递文档本身对此也含糊不清。您能为我解释这些概念吗?
我看到的几乎每个Express应用程序都有app.use
关于中间件的声明,但是我没有找到关于中间件实际上是什么以及该app.use
声明在做什么的清晰,简洁的解释。甚至快递文档本身对此也含糊不清。您能为我解释这些概念吗?
Answers:
我在一个新项目中将中间件的概念分离了一半。
中间件使您可以定义应执行的操作堆栈。Express服务器本身就是一堆中间件。
// express
var app = express();
// middleware
var stack = middleware();
然后您可以通过调用将层添加到中间件堆栈 .use
// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
next();
});
中间件堆栈中的一层是一个函数,该函数接受n个参数(express req
和&表示2个res
)和一个next
函数。
中间件希望该层进行一些计算,增加参数,然后调用next
。
除非您处理堆栈,否则堆栈不会执行任何操作。每当服务器上捕获到传入的HTTP请求时,Express都会处理堆栈。使用中间件,您可以手动处理堆栈。
// express, you need to do nothing
// middleware
stack.handle(someData);
一个更完整的例子:
var middleware = require("../src/middleware.js");
var stack = middleware(function(data, next) {
data.foo = data.data*2;
next();
}, function(data, next) {
setTimeout(function() {
data.async = true;
next();
}, 100)
}, function(data) {
console.log(data);
});
stack.handle({
"data": 42
})
用快速术语来说,您只需定义要快速处理的每个传入HTTP请求的操作堆栈。
就快速(而非连接)而言,您具有全局中间件和特定于路由的中间件。这意味着您可以将中间件堆栈附加到每个传入的HTTP请求,或仅将其附加到与特定路由交互的HTTP请求。
快递和中间件的高级示例:
// middleware
var stack = middleware(function(req, res, next) {
users.getAll(function(err, users) {
if (err) next(err);
req.users = users;
next();
});
}, function(req, res, next) {
posts.getAll(function(err, posts) {
if (err) next(err);
req.posts = posts;
next();
})
}, function(req, res, next) {
req.posts.forEach(function(post) {
post.user = req.users[post.userId];
});
res.render("blog/posts", {
"posts": req.posts
});
});
var app = express.createServer();
app.get("/posts", function(req, res) {
stack.handle(req, res);
});
// express
var app = express.createServer();
app.get("/posts", [
function(req, res, next) {
users.getAll(function(err, users) {
if (err) next(err);
req.users = users;
next();
});
}, function(req, res, next) {
posts.getAll(function(err, posts) {
if (err) next(err);
req.posts = posts;
next();
})
}, function(req, res, next) {
req.posts.forEach(function(post) {
post.user = req.users[post.userId];
});
res.render("blog/posts", {
"posts": req.posts
});
}
], function(req, res) {
stack.handle(req, res);
});
app.use()
语法有些困惑。中间件的实际返回值是use
多少?
我添加一个较晚的答案,以添加先前答案中未提及的内容。
到现在为止,应该清楚中间件是在客户端请求和服务器answer之间运行的功能。所需的最常见中间件功能是错误管理,数据库交互,从静态文件或其他资源获取信息。要在中间件堆栈上移动,必须调用下一个回调,您可以在中间件函数的末尾看到它,以移至流程的下一步。
您可以使用app.use
方法,并有一个流程是这样:
var express = require('express'),
app = express.createServer(),
port = 1337;
function middleHandler(req, res, next) {
console.log("execute middle ware");
next();
}
app.use(function (req, res, next) {
console.log("first middle ware");
next();
});
app.use(function (req, res, next) {
console.log("second middle ware");
next();
});
app.get('/', middleHandler, function (req, res) {
console.log("end middleware function");
res.send("page render finished");
});
app.listen(port);
console.log('start server');
但是您也可以使用另一种方法,并将每个中间件作为函数参数传递。这是来自MooTools Node.js网站的示例,在该示例中,中间件软件将Twitter,Github和Blog流response
发送回给客户端之前。注意函数如何在中作为参数传递app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
。使用app.get
将仅针对GET请求app.use
被调用,而将针对所有请求被调用。
// github, twitter & blog feeds
var githubEvents = require('./middleware/githubEvents')({
org: 'mootools'
});
var twitter = require('./middleware/twitter')();
var blogData = require('./blog/data');
function getLatestBlog(req, res, next){
blogData.get(function(err, blog) {
if (err) next(err);
res.locals.lastBlogPost = blog.posts[0];
next();
});
}
// home
app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
res.render('index', {
title: 'MooTools',
site: 'mootools',
lastBlogPost: res.locals.lastBlogPost,
tweetFeed: res.locals.twitter
});
});
.get()
方法使用3种类型的参数:第一个,最后一个和中间一个。在内部,它检测是否有超过2个参数,并将这些参数(中间的参数)用作中间件函数,并从左至右调用它们。
expressjs 指南对您的问题的回答很简洁,我强烈建议您阅读该指南,我正在发布该指南的一小段内容,该指南相当不错。
中间件功能是可以访问请求对象( req),响应对象( res)和应用程序的请求-响应周期中的下一个功能的函数。下一个功能是Express路由器中的功能,该功能在被调用时将在当前中间件之后执行中间件。
中间件功能可以执行以下任务:
如果当前中间件函数没有结束请求-响应周期,则它必须调用next()将控制权传递给下一个中间件函数。否则,该请求将被挂起。
例
这是一个简单的“ Hello World” Express应用程序的示例。本文的其余部分将定义并向应用程序添加两个中间件功能:一个名为myLogger的用户,它输出一条简单的日志消息,另一个名为requestTime 1,其显示HTTP请求的时间戳。
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
中间件功能myLogger
这是一个称为“ myLogger”的中间件功能的简单示例。当对应用程序的请求通过时,此功能仅显示“已记录”。中间件功能已分配给名为myLogger的变量。
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
注意上面对next()的调用。调用此函数将调用应用程序中的下一个中间件函数。在接下来的()函数不是Node.js的或快递API的一部分,但传递给中间件功能的第三个参数。在接下来的()函数可以被命名为任何东西,但是按照惯例,它总是被命名为“下一个”。为避免混淆,请始终使用此约定。
要加载中间件函数,请调用app.use(),指定中间件函数。例如,以下代码在路由到根路径(/)之前加载myLogger中间件函数。
var express = require('express')
var app = express()
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
app.use(myLogger)
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
每次应用程序收到请求时,它将消息“ LOGGED”打印到终端。
中间件加载的顺序很重要:首先加载的中间件功能也将首先执行。
如果myLogger是在到达根路径的路由之后加载的,则该请求永远不会到达该请求,并且该应用不会打印“ LOGGED”,因为根路径的路由处理程序会终止请求-响应周期。
中间件函数myLogger仅打印一条消息,然后通过调用next()函数将请求传递到堆栈中的下一个中间件函数。
=====非常简单的解释=====
中间件通常在Express.js框架的上下文中使用,并且是node.js的基本概念。简而言之,它基本上是一种可以访问应用程序的请求和响应对象的功能。我想考虑的方式是,在应用程序处理请求之前,要经历一系列“检查/预屏”。例如,中间件非常适合在请求进入应用程序之前确定请求是否已通过身份验证,如果请求未通过身份验证或用于记录每个请求,则返回登录页面。有许多第三方中间件可供使用,这些中间件可以启用各种功能。
简单的中间件示例:
var app = express();
app.use(function(req,res,next)){
console.log("Request URL - "req.url);
next();
}
上面的代码将针对每个进入的请求执行,并记录请求的URL,next()方法实质上允许程序继续。如果未调用next()函数,则该程序将不会继续进行,并且会在中间件执行时停止。
几个中间件陷阱:
next()
但它不会调用而是return next()
。有什么区别?
next()
是因为我们希望下一个中间件被调用,我不认为next()
or return next()
应该有所不同!仍然取决于代码是什么...
保持简单,伙计!
注意:答案与ExpressJS内置的中间件案例有关,但是中间件的定义和使用案例不同。
从我的角度来看,中间件充当实用程序或辅助函数,但通过使用,中间件的激活和使用是完全可选的,app.use('path', /* define or use builtin middleware */)
因为我们不希望我们编写一些代码来执行客户端的每个HTTP请求所需的非常常见的任务例如处理Cookie,CSRF令牌和...,这在大多数应用程序中都很常见,因此中间件可以帮助我们以某种操作的堆栈,顺序或顺序为客户端的每个HTTP请求完成所有这些操作,然后将处理结果提供为客户请求的一个单位。
例:
Web服务器技术的本质是接受客户请求并根据他们的请求向他们提供回复。
想象一下,如果我们仅以“你好,世界!”来回应。向我们的Web服务器的根URI发送GET HTTP请求的文本非常简单,不需要任何其他操作,但是如果我们正在检查当前登录的用户,然后以“你好,用户名!”作为响应,则不需要其他任何内容。在这种情况下,我们需要比平时更多的东西,我们需要一个中间件来处理所有客户端请求元数据,并向我们提供从客户端请求中获取的标识信息,然后根据该信息,我们可以唯一地标识当前用户,并且可以对他进行响应/她并提供一些相关数据。
希望它能帮助到某人!
用最基本的术语来说,如果我想这样解释,我可以从traversymedia youtube频道速成课程中学习。
好的,所以中间件是一个函数,它在您这样调用路由后执行。
var logger = function(req, res, next){
console.log('logging...');
next();
}
app.use(logger);
每次刷新页面时都会执行此记录器功能,这意味着您可以在页面呈现任何操作api调用后基本编写任何内容,然后您可以在其中编写任何内容。并将此中间件放在中间件的路由功能顺序之前非常重要或不起作用