中间件和 app.use 在 Expressjs 中到底意味着什么?
我看到的几乎每个 Express 应用程序都有一个用于中间件的 app.use
语句,但我还没有找到关于中间件实际是什么以及 app.use
的清晰、简洁的解释。声明正在做。即使是 Express 文档本身对此也有些模糊。您能为我解释一下这些概念吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
中间件
我正在一个新项目中分离中间件的概念。
中间件允许您定义应执行的一系列操作。 Express 服务器本身就是一堆中间件。
然后,您可以通过调用
.use
向中间件堆栈添加层。中间件堆栈中的层是一个函数,它接受 n 个参数(2 表示express,
req
& < code>res) 和一个next
函数。中间件期望该层进行一些计算,增加参数,然后调用
next
。除非你处理它,否则堆栈不会做任何事情。每次服务器捕获传入的 HTTP 请求时,Express 都会处理堆栈。使用中间件,您可以手动处理堆栈。
更完整的示例:
用 Express 术语来说,您只需定义希望 Express 为每个传入 HTTP 请求处理的操作堆栈。
就快递(而不是连接)而言,您拥有全局中间件和特定于路由的中间件。这意味着您可以将中间件堆栈附加到每个传入的 HTTP 请求,或者仅将其附加到与特定路由交互的 HTTP 请求。
Express&的进阶范例中间件 :
middleware
I'm halfway through separating the concept of middleware in a new project.
Middleware allows you to define a stack of actions that you should flow through. Express servers themselves are a stack of middlewares.
Then you can add layers to the middleware stack by calling
.use
A layer in the middleware stack is a function, which takes n parameters (2 for express,
req
&res
) and anext
function.Middleware expects the layer to do some computation, augment the parameters and then call
next
.A stack doesn't do anything unless you handle it. Express will handle the stack every time an incoming HTTP request is caught on the server. With middleware you handle the stack manually.
A more complete example :
In express terms you just define a stack of operations you want express to handle for every incoming HTTP request.
In terms of express (rather than connect) you have global middleware and route specific middleware. This means you can attach a middleware stack to every incoming HTTP requests or only attach it to HTTP requests that interact with a certain route.
Advanced examples of express & middleware :
简化之后,Web 服务器可以被视为接收请求并输出响应的函数。因此,如果将Web服务器视为一个功能,则可以将其组织成多个部分,然后将它们分成更小的功能,以便它们的组合将是原始功能。
中间件是您可以与其他人一起编写的较小功能,明显的好处是您可以重用它们。
After simplifying things, a web server can be seen as a function that takes in a request and outputs a response. So if you view a web server as a function, you could organize it into several pieces and separate them into smaller functions so that the composition of them will be the original function.
Middlewares are the smaller functions that you can compose with others and the obvious benefit is that you can reuse them.
我添加了一个较晚的答案,以添加之前答案中未提及的内容。
现在应该很清楚了,中间件是在客户端请求和服务器应答之间运行的函数。最常见的中间件功能是错误管理、数据库交互、从静态文件或其他资源获取信息。要在中间件堆栈上移动,必须调用下一个回调,您可以在中间件函数的末尾看到它以移动到流程中的下一步。
您可以使用
app.use
方法并拥有这样的流程:但您也可以使用另一种方法并将每个中间件作为函数参数传递。这是来自 MooTools Nodejs 网站的 示例,其中中间件获取 Twitter、Github以及将
响应
发送回之前的博客流 客户。请注意函数如何作为app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
) 中的参数传递。使用app.get
将仅针对 GET 请求调用,app.use
将为所有请求调用。I add a late answer to add something not mentioned in the previous answers.
By now it should be clear that middleware is/are function(s) run between the client request and the server answer. The most common middleware functionality needed are error managing, database interaction, getting info from static files or other resources. To move on the middleware stack the next callback must be called, you can see it in the end of middleware function to move to the next step in the flow.
You can use the
app.use
approach and have a flow like this:but you can also use another approach and pass each middleware as function arguments. Here is a example from the MooTools Nodejs website where midleware gets the Twitter, Github and Blog flow before the
response
is sent back to the client. Note how the functions are passed as arguments inapp.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
. Usingapp.get
will only be called for GET requests,app.use
will be called for all requests.expressjs 指南 对您的问题有非常简洁的答案,我强烈建议您阅读,我发布了该指南的一小段,该指南相当不错。
编写用于 Express 应用程序的中间件
概述
中间件函数是有权访问 请求对象 (req),响应object (res),以及应用程序请求-响应周期中的下一个函数。下一个函数是 Express 路由器中的一个函数,当被调用时,它会执行当前中间件之后的中间件。
中间件函数可以执行以下任务:
如果当前的中间件函数没有结束请求-响应周期,它必须调用next()将控制权传递给下一个中间件函数。否则,请求将被挂起。
示例
这是一个简单的“Hello World” Express 应用程序的示例。本文的其余部分将定义并向应用程序添加两个中间件函数:一个名为 myLogger,用于打印简单的日志消息,另一个名为 requestTime1 显示 HTTP 请求的时间戳。
中间件函数 myLogger
这是一个名为“myLogger”的中间件函数的简单示例。当对应用程序的请求通过该函数时,该函数仅打印“LOGGED”。中间件函数被分配给名为 myLogger 的变量。
要加载中间件函数,请调用app.use(),并指定中间件函数。例如,以下代码在路由到根路径 (/) 之前加载 myLogger 中间件函数。
每次应用程序收到请求时,都会将消息“LOGGED”打印到终端。
中间件加载的顺序很重要:首先加载的中间件函数也首先执行。
如果 myLogger 在路由到根路径之后加载,则请求永远不会到达它,并且应用程序不会打印“LOGGED”,因为根路径的路由处理程序终止了请求-响应周期。
中间件函数myLogger只是打印一条消息,然后通过调用next()函数将请求传递给堆栈中的下一个中间件函数。
expressjs guide has pretty neat answer to your question, I highly recommend you to read that, I am posting a short snippet of the guide, the guide is quite good.
Writing middleware for use in Express apps
Overview
Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.
Middleware functions can perform the following tasks:
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.
Example
Here is an example of a simple “Hello World” Express application. The remainder of this article will define and add two middleware functions to the application: one called myLogger that prints a simple log message and another called requestTime1 that displays the timestamp of the HTTP request.
Middleware function myLogger
Here is a simple example of a middleware function called “myLogger”. This function just prints “LOGGED” when a request to the app passes through it. The middleware function is assigned to a variable named myLogger.
To load the middleware function, call app.use(), specifying the middleware function. For example, the following code loads the myLogger middleware function before the route to the root path (/).
Every time the app receives a request, it prints the message “LOGGED” to the terminal.
The order of middleware loading is important: middleware functions that are loaded first are also executed first.
If myLogger is loaded after the route to the root path, the request never reaches it and the app doesn’t print “LOGGED”, because the route handler of the root path terminates the request-response cycle.
The middleware function myLogger simply prints a message, then passes on the request to the next middleware function in the stack by calling the next() function.
=====非常非常简单的解释=====
中间件通常在 Express.js 框架的上下文中使用,是 Node.js 的基本概念。简而言之,它基本上是一个可以访问应用程序的请求和响应对象的函数。我想考虑的方式是,请求在由应用程序处理之前要经过一系列“检查/预筛选”。例如,中间件非常适合在请求继续到应用程序之前确定请求是否经过身份验证,如果请求未经身份验证,则返回登录页面,或者用于记录每个请求。有许多第三方中间件可以实现各种功能。
简单中间件示例:
上面的代码将针对每个传入的请求执行,并记录请求 url,next() 方法本质上允许程序继续。如果不调用 next() 函数,程序将不会继续执行,并会在中间件执行时停止。
几个中间件陷阱:
=====Very very simple explanation=====
Middlewares are often used in the context of Express.js framework and are a fundamental concept for node.js . In a nutshell, Its basically a function that has access to the request and response objects of your application. The way I'd like to think about it, is a series of 'checks/pre-screens' that the request goes through before the it is handled by the application. For e.g, Middlewares would be a good fit to determine if the request is authenticated before it proceeds to the application and return the login page if the request is not authenticated or for logging each request. A lot of third-party middlewares are available that enables a variety of functionality.
Simple Middleware example:
The above code would be executed for each request that comes in and would log the request url, the next() method essentially allows the program to continue. If the next() function is not invoked, the program would not proceed further and would halt at the execution of the middleware.
A couple of Middleware Gotchas:
中间件是在输入/源产生输出之后在中间执行的函数,该输出可能是最终输出,也可能被下一个中间件使用,直到循环完成。
它就像一个经过装配线的产品,在运行过程中不断修改,直到完成、评估或被拒绝。
中间件期望某些值起作用(即参数值),并且基于某种逻辑,中间件将调用或不调用下一个中间件或将响应发送回客户端。
如果您仍然无法掌握中间件概念,它的方式类似于装饰器或命令链模式。
Middlewares are functions executed in the middle after the input/source then produces an output which could be the final output or could be used by the next middleware until the cycle is complete.
It is like a product that goes through an assembly line where it gets modified as it moves along until it gets completed, evaluated or gets rejected.
A middleware expects some value to work on (i.e. parameter values) and based on some logic the middleware will call or not call the next middleware or send a response back to the client.
If you can't still grasp the middleware concept, it is in a way similar to the Decorator or Chain of command patterns.
中间件是在调用用户定义的处理程序之前由 Express js 路由层调用的链式函数的子集。中间件函数可以完全访问请求和响应对象,并且可以修改其中任何一个。
中间件链始终按照其定义的确切顺序进行调用,因此准确了解特定中间件正在执行的操作对于您而言至关重要。
一旦中间件函数完成,它就会调用中的下一个函数通过调用其下一个参数作为函数来调用链。
执行完整链后,调用用户请求处理程序。
Middleware is a subset of chained functions called by the Express js routing layer before the user-defined handler is invoked. Middleware functions have full access to the request and response objects and can modify either of them.
The middleware chain is always called in the exact order in which it has been defined, so it is vital for you to know exactly what a specific piece of middleware is doing.
Once a middleware function finishes, it calls the next function in the chain by invoking its next argument as function.
After the complete chain gets executed,the user request handler is called.
让事情变得简单,伙计!
注意:答案与 ExpressJS 内置中间件案例相关,但是中间件有不同的定义和用例。
从我的角度来看,中间件充当实用程序或辅助函数,但其激活和使用是完全可选的,通过使用
app.use('path', /* 定义或使用内置中间件 * /)
它不想让我们编写一些代码来执行非常常见的任务,这些任务是我们客户端的每个 HTTP 请求所需的,例如处理 cookie、CSRF 令牌等等,这些在大多数应用程序中都很常见所以中间件可以帮助我们为每个人完成所有这些我们的客户端在某些堆栈、操作序列或顺序中发出 HTTP 请求,然后将处理结果作为客户端请求的单个单元提供。示例:
接受客户端请求并根据请求提供响应是 Web 服务器技术的本质。
想象一下,如果我们只提供“Hello,world!”的响应。向我们的网络服务器的根 URI 发送 GET HTTP 请求的文本是非常简单的场景,不需要任何其他内容,但如果我们检查当前登录的用户,然后用“Hello, Username!”进行响应需要比平常更多的东西,在这种情况下,我们需要一个中间件来处理所有客户端请求元数据,并向我们提供从客户端请求中获取的标识信息,然后根据该信息,我们可以唯一地标识我们当前的用户,并且可以响应他/她以及一些相关数据。
希望它能帮助别人!
Keep things simple, man!
Note: the answer is related to the ExpressJS builtin middlware cases, however there are different definitions and use cases of middlewares.
From my point of view, middleware acts as utility or helper functions but its activation and use is fully optional by using the
app.use('path', /* define or use builtin middleware */)
which don't wants from us to write some code for doing very common tasks which are needed for each HTTP request of our client like processing cookies, CSRF tokens and ..., which are very common in most applications so middleware can help us do these all for each HTTP request of our client in some stack, sequence or order of operations then provide the result of the process as a single unit of client request.Example:
Accepting clients requests and providing back responses to them according to their requests is the nature of web server technology.
Imagine if we are providing a response with just "Hello, world!" text for a GET HTTP request to our webserver's root URI is very simple scenario and don't needs anything else, but instead if we are checking the currently logged-in user and then responding with "Hello, Username!" needs something more than usual in this case we need a middleware to process all the client request metadata and provide us the identification info grabbed from the client request then according to that info we can uniquely identify our current user and it is possible to response to him/her with some related data.
Hope it to help someone!
用非常基本的术语来说,如果我想像这样解释它,我是从 traversymedia youtube 频道快速速成课程中学到的。
好的,中间件是一个在您像这样调用路由后执行的函数。
每次刷新页面时都会执行此记录器函数,这意味着您可以在页面呈现任何操作 api 调用后在其中写入所需执行的任何操作,基本上重置任何内容。并将此中间件放在您的路由功能之前 中间件的顺序非常重要,否则它将不起作用
In very basic term if i want to explain it like this i learn this from traversymedia youtube channel express crash course.
ok so middle ware is a function who execute after you make a call to your route like this.
This logger function execute every time you refresh your page that means you can write anything in it that you required to do after your page get rendered any operation api call, reset things basically anything. and put this middleware before your route function order of middleware is really important or it dons't work