中间件
注意上面的调用
next()
。调用此函数会调用应用程序中的下一个中间件函数。该next()
函数不是Node.js或Express API的一部分,而是传递给中间件函数的第三个参数。该next()
函数可以命名为任何东西,但按照惯例,它总是被命名为“next”。为避免混淆,请始终使用此约定。
中间件函数可以执行以下任务:
-
执行任何代码。
-
对请求和响应对象进行更改。
-
结束请求/响应循环。
-
调用堆栈中的下一个中间件函数。
如果当前中间件函数没有结束请求/响应循环,那么它必须调用 next()
,以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。
结束请求/响应循环:如果一个中间件函数决定结束请求-响应循环,它可以通过发送一个响应(例如,调用
res.send()
或res.json()
)来直接向客户端发送响应。一旦这样做了,请求-响应循环就结束了,后续的中间件将不会被执行。调用
next()
:如果中间件函数没有结束请求-响应循环,它必须调用next()
函数。这样做会将控制权传递给下一个中间件函数,允许请求继续在中间件栈中流动。如果当前中间件是栈中的最后一个,调用next()
会导致一个错误,因为后面没有更多的中间件来处理请求。请求挂起状态:如果一个中间件函数既没有结束请求-响应循环,也没有调用
next()
,那么请求就会处于挂起状态,既不会发送响应给客户端,也不会继续执行后续的中间件。这通常是一个错误,因为它会导致服务不可用,客户端会一直等待响应。
分类
express可以使用的中间件类型
应用层中间件
使用 app.use()
和 app.METHOD()
函数将应用层中间件绑定到应用程序对象的实例
例子
路由处理程序使您可以为一个路径定义多个路由。以下示例为针对 /user/:id
路径的 GET 请求定义两个路由。第二个路由不会导致任何问题,但是永远都不会被调用,因为第一个路由结束了请求/响应循环。
此示例显示一个中间件子堆栈,用于处理针对 /user/:id
路径的 GET 请求。
app.get('/user/:id', function (req, res, next) {
console.log('ID:', req.params.id);
next();
}, function (req, res, next) {
res.send('User Info');
});
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', function (req, res, next) {
res.end(req.params.id);
});
要跳过路由器中间件堆栈中剩余的中间件函数,请调用 next('route')
将控制权传递给下一个路由。
注:next('route')
仅在使用 app.METHOD()
或 router.METHOD()
函数装入的中间件函数中有效。
此示例显示一个中间件子堆栈,用于处理针对 /user/:id
路径的 GET 请求。
app.get('/user/:id', function (req, res, next) {
// 当用户id为0的时候,跳到下一个路由处理其
if (req.params.id == 0) next('route');
// 其他情况则将控制权给当前中间件栈中的下一个中间件函数
else next(); //
}, function (req, res, next) {
// render a regular page
res.render('regular');
});
// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {
res.render('special');
});
路由器层中间件
路由器层中间件的工作方式与应用层中间件基本相同,差异之处在于它绑定到 express.Router()
的实例。
const router = express.Router();
使用 router.use()
和 router.METHOD()
函数装入路由器层中间件。
错误处理中间件
错误处理中间件始终采用四个自变量。必须提供四个自变量,以将函数标识为错误处理中间件函数。即使无需使用 next
对象,也必须指定该对象以保持特征符的有效性。否则,next
对象将被解释为常规中间件,从而无法处理错误。
错误处理中间件函数的定义方式与其他中间件函数基本相同,差别在于错误处理函数有四个自变量而不是三个,专门具有特征符 (err, req, res, next)
:
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
有关错误处理中间件的详细信息,请参阅:错误处理。
内置中间件
Express 中唯一内置的中间件函数是 express.static
。
express.static托管静态资源
express 提供了一个非常好用的函数,叫做express.static(),通过它,我们可以非常方便地创建一个静态资源服务器, 例如,通过如下代码就可以将public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:
app.use(express.static('public'))
现在,你就可以访问public 目录中的所有文件了:
http://localhost:3000/images/bg.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/login.js
注意:Express 在指定的静态目录中查找文件,并对外提供资源的访问路径。 因此,存放静态文件的目录名不会出现在URL 中。
托管多个静态资源目录
如果要托管多个静态资源目录,请多次调用express.static() 函数:
app.use(express.static('public'))
app. use(express.static('files'))
访问静态资源文件时,express.static() 函数会根据目录的添加顺序查找所需的文件。
第三方中间件
使用第三方中间件向 Express 应用程序添加功能。
安装具有所需功能的 Node.js 模块,然后在应用层或路由器层的应用程序中将其加装入。
以下示例演示如何安装和装入 cookie 解析中间件函数 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());
有关 Express 常用的第三方中间件函数的部分列表,请参阅:第三方中间件。