Using middleware使用中间件
Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls.Express是一个路由和中间件web框架,它本身的功能很小:Express应用程序本质上是一系列中间件函数调用。
Middleware functions are functions that have access to the request object (中间件函数是可以访问请求对象(req
), the response object (res
), and the next middleware function in the application’s request-response cycle. req
)、响应对象(res
)和应用程序请求-响应周期中的下一个中间件函数的函数。The next middleware function is commonly denoted by a variable named 下一个中间件函数通常由名为next
.next
的变量表示。
Middleware functions can perform the following tasks:中间件功能可以执行以下任务:
Execute any code.执行任何代码。Make changes to the request and the response objects.对请求和响应对象进行更改。End the request-response cycle.结束请求响应周期。Call the next middleware function in the stack.调用堆栈中的下一个中间件函数。
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.next()
将控制传递给下一个中间件函数。否则,请求将被搁置。
An Express application can use the following types of middleware:Express应用程序可以使用以下类型的中间件:
Application-level middleware应用级中间件Router-level middleware路由器级中间件Error-handling middleware错误处理中间件Built-in middleware内置中间件Third-party middleware第三方中间件
You can load application-level and router-level middleware with an optional mount path.您可以使用可选的装载路径加载应用程序级和路由器级中间件。
You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point.您还可以一起加载一系列中间件函数,这将在装载点创建中间件系统的子堆栈。
Application-level middleware应用级中间件
Bind application-level middleware to an instance of the app object by using the 使用app.use()
and app.METHOD()
functions, where METHOD
is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.app.use()
和app.METHOD()
函数将应用程序级中间件绑定到app
对象的实例,其中METHOD
是中间件函数处理的请求的HTTP方法(如GET、PUT或POST),小写。
This example shows a middleware function with no mount path. The function is executed every time the app receives a request.此示例显示了一个没有装载路径的中间件函数。每次应用程序收到请求时,都会执行该函数。
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('Time:', Date.now())
next()
})
This example shows a middleware function mounted on the 此示例显示了安装在/user/:id
path. The function is executed for any type of
HTTP request on the /user/:id
path./user/:id
路径上的中间件函数。该函数对/user/:id
路径上的任何类型的HTTP请求执行。
app.use('/user/:id', (req, res, next) => {
console.log('Request Type:', req.method)
next()
})
This example shows a route and its handler function (middleware system). The function handles GET requests to the 此示例显示了路由及其处理程序功能(中间件系统)。该函数处理对/user/:id
path./user/:id
路径的GET请求。
app.get('/user/:id', (req, res, next) => {
res.send('USER')
})
Here is an example of loading a series of middleware functions at a mount point, with a mount path.下面是一个在装载点加载一系列中间件函数的示例,其中包含装载路径。
It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the 它说明了一个中间件子栈,该子栈将任何类型的HTTP请求的请求信息打印到/user/:id
path./user/:id
路径。
app.use('/user/:id', (req, res, next) => {
console.log('Request URL:', req.originalUrl)
next()
}, (req, res, next) => {
console.log('Request Type:', req.method)
next()
})
Route handlers enable you to define multiple routes for a path. 路由处理程序使您能够为路径定义多个路由。The example below defines two routes for GET requests to the 下面的示例定义了GET请求到/user/:id
path. /user/:id
路径的两条路由。The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle.第二条路由不会引起任何问题,但它永远不会被调用,因为第一条路由结束了请求-响应周期。
This example shows a middleware sub-stack that handles GET requests to the 此示例显示了一个处理对/user/:id
path./user/:id
路径的GET请求的中间件子堆栈。
app.get('/user/:id', (req, res, next) => {
console.log('ID:', req.params.id)
next()
}, (req, res, next) => {
res.send('User Info')
})
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', (req, res, next) => {
res.send(req.params.id)
})
To skip the rest of the middleware functions from a router middleware stack, call 要跳过路由器中间件堆栈中的其余中间件功能,请调用next('route')
to pass control to the next route.next('route')
将控制权传递给下一个路由。
Note
next('route')
will work only in middleware functions that were loaded by using the app.METHOD()
or router.METHOD()
functions.next('route')
只适用于使用app.METHOD()
或router.METHOD()
函数加载的中间件函数。
This example shows a middleware sub-stack that handles GET requests to the 此示例显示了一个处理对/user/:id
path./user/:id
路径的GET请求的中间件子堆栈。
app.get('/user/:id', (req, res, next) => {
// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route')
// otherwise pass the control to the next middleware function in this stack
else next()
}, (req, res, next) => {
// send a regular response
res.send('regular')
})
// handler for the /user/:id path, which sends a special response
app.get('/user/:id', (req, res, next) => {
res.send('special')
})
Middleware can also be declared in an array for reusability.中间件也可以在数组中声明以实现可重用性。
This example shows an array with a middleware sub-stack that handles GET requests to the 此示例显示了一个具有中间件子堆栈的数组,该子堆栈处理对/user/:id
path/user/:id
路径的GET请求
function logOriginalUrl (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}
function logMethod (req, res, next) {
console.log('Request Type:', req.method)
next()
}
const logStuff = [logOriginalUrl, logMethod]
app.get('/user/:id', logStuff, (req, res, next) => {
res.send('User Info')
})
Router-level middleware路由器级中间件
Router-level middleware works in the same way as application-level middleware, except it is bound to an instance of 路由器级中间件的工作方式与应用程序级中间件相同,除了它绑定到express.Router()
.express.Router()
的实例。
const router = express.Router()
Load router-level middleware by using the 使用router.use()
and router.METHOD()
functions.router.use()
和router.METHOD()
函数加载路由器级中间件。
The following example code replicates the middleware system that is shown above for application-level middleware, by using router-level middleware:以下示例代码通过使用路由器级中间件复制了上面显示的应用程序级中间件的中间件系统:
const express = require('express')
const app = express()
const router = express.Router()
// a middleware function with no mount path. This code is executed for every request to the router
router.use((req, res, next) => {
console.log('Time:', Date.now())
next()
})
// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use('/user/:id', (req, res, next) => {
console.log('Request URL:', req.originalUrl)
next()
}, (req, res, next) => {
console.log('Request Type:', req.method)
next()
})
// a middleware sub-stack that handles GET requests to the /user/:id path
router.get('/user/:id', (req, res, next) => {
// if the user ID is 0, skip to the next router
if (req.params.id === '0') next('route')
// otherwise pass control to the next middleware function in this stack
else next()
}, (req, res, next) => {
// render a regular page
res.render('regular')
})
// handler for the /user/:id path, which renders a special page
router.get('/user/:id', (req, res, next) => {
console.log(req.params.id)
res.render('special')
})
// mount the router on the app
app.use('/', router)
To skip the rest of the router’s middleware functions, call 要跳过路由器的其余中间件功能,请调用next('router')
to pass control back out of the router instance.next('router')
将控制权传递回路由器实例。
This example shows a middleware sub-stack that handles GET requests to the 此示例显示了一个处理对/user/:id
path./user/:id
路径的GET请求的中间件子堆栈。
const express = require('express')
const app = express()
const router = express.Router()
// predicate the router with a check and bail out when needed
router.use((req, res, next) => {
if (!req.headers['x-auth']) return next('router')
next()
})
router.get('/user/:id', (req, res) => {
res.send('hello, user!')
})
// use the router and 401 anything falling through
app.use('/admin', router, (req, res) => {
res.sendStatus(401)
})
Error-handling middleware错误处理中间件
Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. 错误处理中间件总是需要四个参数。您必须提供四个参数来将其标识为错误处理中间件函数。Even if you don’t need to use the 即使不需要使用next
object, you must specify it to maintain the signature. next
对象,也必须指定它来维护签名。Otherwise, the 否则,next
object will be interpreted as regular middleware and will fail to handle errors.next
对象将被解释为常规中间件,无法处理错误。
Define error-handling middleware functions in the same way as other middleware functions, except with four arguments instead of three, specifically with the signature 以与其他中间件函数相同的方式定义错误处理中间件函数,除了使用四个参数而不是三个参数,特别是使用签名(err, req, res, next)
:(err, req, res, next)
:
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})
For details about error-handling middleware, see: 有关错误处理中间件的详细信息,请参阅:错误处理。Error handling错误处理.
Built-in middleware内置中间件
Starting with version 4.x, Express no longer depends on Connect. 从4x版本开始,Express不再依赖于Connect。The middleware
functions that were previously included with Express are now in separate modules; see the list of middleware functions.以前包含在Express中的中间件功能现在位于单独的模块中;请参阅中间件功能列表。
Express has the following built-in middleware functions:Express具有以下内置中间件功能:
- express.static
serves static assets such as HTML files, images, and so on.提供HTML文件、图像等静态资产。 - express.json
parses incoming requests with JSON payloads.使用JSON有效载荷解析传入请求。NOTE: Available with Express 4.16.0+注:Express 4.16.0提供此功能+ - express.urlencoded
parses incoming requests with URL-encoded payloads.使用URL编码的有效载荷解析传入请求。NOTE: Available with Express 4.16.0+注:Express 4.16.0提供此功能+
Third-party middleware第三方中间件
Use third-party middleware to add functionality to Express apps.使用第三方中间件为Express应用程序添加功能。
Install the Node.js module for the required functionality, then load it in your app at the application level or at the router level.安装Node.js模块以实现所需功能,然后在应用程序级别或路由器级别将其加载到您的应用程序中。
The following example illustrates installing and loading the cookie-parsing middleware function 以下示例说明了如何安装和加载cookie解析中间件函数cookie-parser
.cookie-parser
。
$ npm install cookie-parser
const express = require('express')
const app = express()
const cookieParser = require('cookie-parser')
// load the cookie-parsing middleware
app.use(cookieParser())
For a partial list of third-party middleware functions that are commonly used with Express, see: Third-party middleware.有关Express中常用的第三方中间件功能的部分列表,请参阅:第三方中间件。