我看到的几乎每个Express应用程序都有一个app.use中间件声明,但我没有找到一个清晰,简洁的解释,说明中间件实际上是什么以及app.use声明正在做什么.即便是快递文件本身也有点模糊.你能帮我解释一下这些概念吗?
Ray*_*nos 104
我正在将新项目中间件的概念分离出来.
中间件允许您定义应该流经的一系列操作.Express服务器本身就是一堆中间件.
// express
var app = express();
// middleware
var stack = middleware();
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过调用将层添加到中间件堆栈 .use
// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
next();
});
Run Code Online (Sandbox Code Playgroud)
中间件堆栈中的一个层是一个函数,它接受n个参数(2表示快速,req&res)和一个next函数.
中间件期望该层进行一些计算,扩充参数然后调用next.
除非您处理它,否则堆栈不会执行任何操作.每次在服务器上捕获传入的HTTP请求时,Express都将处理堆栈.使用中间件,您可以手动处理堆栈.
// express, you need to do nothing
// middleware
stack.handle(someData);
Run Code Online (Sandbox Code Playgroud)
一个更完整的例子:
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
})
Run Code Online (Sandbox Code Playgroud)
在明确的术语中,您只需为每个传入的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);
});
Run Code Online (Sandbox Code Playgroud)
Bar*_*Rho 58
在简化事物之后,可以将Web服务器视为接收请求并输出响应的函数.因此,如果您将Web服务器视为一个函数,您可以将它组织成几个部分并将它们分成更小的函数,以便它们的组合将是原始函数.
中间件是您可以与其他人合并的较小功能,显而易见的好处是您可以重复使用它们.
Ser*_*gio 30
我添加一个迟到的答案来添加以前答案中未提及的内容.
到目前为止,应该清楚中间件是在客户端请求和服务器应答之间运行的功能.所需的最常见的中间件功能是错误管理,数据库交互,从静态文件或其他资源获取信息.要移动中间件堆栈,必须调用下一个回调,您可以在中间件函数的末尾看到它以移动到流程的下一步.
您可以使用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');
Run Code Online (Sandbox Code Playgroud)
但您也可以使用其他方法并将每个中间件作为函数参数传递.以下是MooTools Nodejs网站的一个示例,其中midleware在response发送回客户端之前获取Twitter,Github和Blog流.注意函数如何作为参数传递app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){.app.get只会为GET请求调用using ,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
});
});
Run Code Online (Sandbox Code Playgroud)
Sur*_*ain 17
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)
Run Code Online (Sandbox Code Playgroud)
中间件功能myLogger
这是一个名为"myLogger"的中间件函数的简单示例.当对应用程序的请求通过时,此函数只打印"LOGGED".中间件函数被分配给名为myLogger的变量.
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
Run Code Online (Sandbox Code Playgroud)
注意上面的调用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)
Run Code Online (Sandbox Code Playgroud)
每次应用程序收到请求时,它都会向终端输出消息"LOGGED".
中间件加载的顺序很重要:首先加载的中间件函数也会先执行.
如果myLogger在到达根路径的路径之后加载,则请求永远不会到达,并且应用程序不会打印"LOGGED",因为根路径的路由处理程序会终止请求 - 响应周期.
中间件函数myLogger只是打印一条消息,然后通过调用next()函数将请求传递给堆栈中的下一个中间件函数.
小智 9
=====很简单的解释=====
中间件通常在Express.js框架的上下文中使用,并且是node.js的基本概念.简而言之,它基本上是一个可以访问应用程序的请求和响应对象的函数.我想要考虑的方式是一系列"检查/预筛选",请求在应用程序处理之前经过.例如,中间件很适合确定请求在进入应用程序之前是否经过身份验证,如果请求未经过身份验证则返回登录页面,或者用于记录每个请求.许多第三方中间件可用于实现各种功能.
简单中间件示例:
var app = express();
app.use(function(req,res,next)){
console.log("Request URL - "req.url);
next();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码将针对每个请求执行并记录请求url,next()方法基本上允许程序继续.如果未调用next()函数,则程序将不会继续进行并且将在执行中间件时停止.
几个中间件陷阱:
中间件是在输入/源之后在中间执行的函数,然后产生输出,该输出可以是最终输出,或者可以由下一个中间件使用直到循环完成.
它就像一个产品通过装配线,在它移动时会被修改,直到它完成,评估或被拒绝.
中间件需要处理某些值(即参数值),并基于某些逻辑,中间件将调用或不调用下一个中间件或将响应发送回客户端.
如果您仍然无法掌握中间件概念,那么它的方式与装饰器或命令链模式类似.
中间件是在调用用户定义的处理程序之前由Express js路由层调用的链接函数的子集.中间件函数可以完全访问请求和响应对象,并可以修改它们中的任何一个.
中间件链始终按照其定义的确切顺序进行调用,因此确切了解特定中间件的作用至关重要.
中间件函数完成后,它会通过调用其下一个参数作为函数来调用链中的下一个函数.
完成链完成后,将调用用户请求处理程序.
| 归档时间: |
|
| 查看次数: |
82142 次 |
| 最近记录: |