介绍
Middleware 是将生命周期方法执行到 Express 服务器的功能,并使用请求和响应周期。Express.js 提供内置的中间软件,并允许您生产自定义版本,以实现精确的功能,例如阻止用户执行特定操作或记录到您的应用程序的接入请求的路径。
在本文中,您将了解如何在 Express.js 中创建自定义中间件。
前提条件
要跟随这篇文章,你将需要:
要了解更多关于 Node.js 的信息,请参阅我们的 如何在 Node.js 中编码系列
- 对
请求和响应周期的一般了解。 请参阅我们关于 如何在 Express 中使用req' 对象](https://andsky.com/tech/tutorials/nodejs-req-object-in-expressjs)和 [如何在 Express 中使用res' 对象的教程。
分析一个 Express Middleware
Express.js 中的所有中间件函数都接受请求、响应和下一步生命周期方法的三个参数,在您的 index.js 文件中,将使用三个生命周期方法的函数定义为参数:
1[label index.js]
2function myCustomMiddleware(req, res, next) {
3 // ...
4}
第一个参数req是指具有内置属性的请求对象,用于访问客户端数据并促进 HTTP 请求。 res 参数是具有内置方法的响应对象,用于通过 HTTP 请求将数据发送到客户端。
Middleware有能力修改req和res对象,运行您想要的任何代码,结束请求和响应周期,并继续以下函数。
注意你的中间件的顺序,因为在每一个前面的中间件中需要引用‘next()’函数。
现在你已经审查了构建中间件的三个论点,让我们看看如何组装自定义中间件。
使用req对象
要识别当前登录的用户,您可以构建一个自定义中间软件,可以通过身份验证步骤来检索用户。
1[label middleware/setCurrentUser.js]
2// Require in logic from your authentication controller
3const getUserFromToken = require("../getUserFromToken");
4
5module.exports = function setCurrentUser(req, res, next) {
6 const token = req.header("authorization");
7
8 // look up the user based on the token
9 const user = getUserFromToken(token).then(user => {
10 // append the user object the the request object
11 req.user = user;
12
13 // call next middleware in the stack
14 next();
15 });
16};
在您的 setCurrentUser() 函数中, req 对象应用了内置 .header() 方法,以返回用户的访问代码。 使用验证控制器方法, getUserFromToken(),您的 req.header() 逻辑作为一个参数来搜索用户基于其代码。 您也可以使用 req 对象来定义一个自定义属性, .user 来存储用户的信息。
您可以在 Express 服务器中启用自定义中间件,通过应用内置的 Express.js 中间件, .use()。
在你的「server.js」文件中,实例化一个Express的实例,并在你的「setCurrentUser()」中要求自定义的中间软件:
1[label server.js]
2const express = require('express');
3
4const setCurrentUser = require('./middleware/setCurrentUser.js');
5
6const app = express();
7
8app.use(setCurrentUser);
9
10// ...
app.use()中间软件接受你的自定义中间软件作为一个论点,并授权你的逻辑在你的Express服务器。
应用res对象
您还可以创建自定义中间件来处理响应对象的功能,例如设计新标题。
在addNewHeader.js文件中,定义一个函数,并在res对象上使用.setHeader()方法:
1[label middleware/addNewHeader.js]
2module.exports = function addNewHeader(req, res, next) {
3 res.setHeader("X-New-Policy", "Success");
4 next();
5};
在这里,‘.setHeader()’ 方法将在每个函数调用中应用新的标题,即‘成功’。
结束请求和响应循环
Express.js 还允许您在自定义中间件中结束请求和响应循环。
在isLoggedIn.js文件中,定义一个函数并设置一个条件,以检查用户的数据是否存在于req对象上:
1[label middleware/isLoggedIn.js]
2module.exports = function isLoggedIn(req, res, next) {
3 if (req.user) {
4 next();
5 } else {
6 // return unauthorized
7 res.send(401, "Unauthorized");
8 }
9};
如果用户的数据存在于req对象中,您的自定义中间软件将继续执行以下函数. 如果特定用户的数据不在对象中,则对象上的.send()方法将发送错误状态代码401和消息到客户端。
设置中间件后,导出文件并导航到您的 Express.js 服务器. 在您的 server.js 文件中,请请求并插入自定义中间件作为一个 GET 请求的论点,以通过单一路径验证用户:
1[label server.js]
2const express = require("express");
3
4const setCurrentUser = require("./middleware/setCurrentUser.js");
5const isLoggedIn = require("./middleware/isLoggedIn.js");
6
7const app = express();
8
9app.use(setCurrentUser);
10
11app.get("/users", isLoggedIn, function(req, res) {
12 // ...
13});
路由器 /users 处理您的 isLoggedIn 自定义中间件中的逻辑。 根据您的 Express 服务器的顺序,路由器也可以访问 setCurrentUser 中间件,因为它在您的 GET 请求之前被定义。
结论
Express.js为您提供了在内置方法之外自定义中间件的能力,通过用户身份验证和他们的数据进行审查。
有关编写自定义 Express.js 中间件的进一步阅读,请访问 Express.js 网站上的 官方文档。