Node.js 中间件的工作原理

Node.js 中间件的工作原理

视频教程推荐:node js教程

什么是 Express 中间件

中间件在字面上的意思是你在软件的一层和另一层中间放置的任何东西。Express 中间件是在对 Express 服务器请求的生命周期内所执行的函数。每个中间件都可以访问其被附加到的所有路由的 HTTP 请求和响应。另外,中间件可以终止 HTTP 请求,也可以用 next 将其传递给另一个中间件函数。中间件的这种“链”使你可以对代码进行划分并创建可重用的中间件。

编写 Express 中间件的要求

你需要安装一些东西来创建、使用和测试 express 中间件。首先需要 node 和 npm。为确保已经安装,可以运行:

npm -v && node -v

登录后复制

你应该看到已安装的 Node 和 NPM 版本。如果出现错误,则需要安装 Node。所有例子都应在 Node ver 8+ 和NPM ver 5+ 下使用。

本文使用了 Express 4.x 版。这很重要,因为从 3.x 版到 4.x 版有重大的更改。

Express中间件:基础

首先我们使用 Express 最基本的内置中间件。创建一个新项目并 npm 初始化它…

npm initnpm install express --saveCreate server.js and paste the following code:const express = require('express');const app = express();app.get('/', (req, res, next) => {  res.send('Welcome Home');});app.listen(3000);

登录后复制

中间件解决什么问题?为什么要用它?

假设你在 web 网络服务器上正在使用 Node.js 和 Express 运行Web应用程序。在此应用中,你需要登录的某些页面。

当 Web 服务器收到数据请求时,Express 将为你提供一个请求对象,其中包含有关用户及其所请求数据的信息。 Express 还使你可以访问响应对象,可以在Web服务器响应用户之前对其进行修改。这些对象通常缩短为 reqres

中间件函数是使用相关信息修改 reqres 对象的理想场所。例如用户登录后,你可以从数据库中获取其用户详细信息,然后将这些详细信息存储在 res.user 中。

中间件函数是什么样的?

async function userMiddleware (req, res, next) {    try {        const userData = await getUserData(req.params.id);  //see app.get below        if(userData) {                req.user = userData;                next();        }    } catch(error)  {        res.status(500).send(error.message); //replace with proper error handling    }}

登录后复制

如果出现错误,并且你不想执行其他代码,则不要调用该函数。请记住在这种情况下要发送响应,否则客户端将会等待响应直到超时。

var app = express();//your normal route Handlersapp.get('/user/:id', userMiddleware, userController);

登录后复制

中间件链

你可以在中间件数组中或着通过使用多个 app.use 调用来链接中间件:

app.use(middlewareA);app.use(middlewareB);app.get('/', [middlewareC, middlewareD], handler);

登录后复制

Express 收到请求后,与请求相匹配的每个中间件都将会按照初始化的顺序运行,直到有终止操作为止。

2.png

因此,如果发生错误,则将按顺序调用所有用于处理错误的中间件,直到其中一个不再调用 next() 函数调用为止。

Express中间件的类型

路由器级中间件,例如:router.use内置中间件,例如:express.static,express.json,express.urlencoded错误处理中间件,例如:app.use(err,req,res,next)第三方中间件,例如:bodyparser、cookieparser路由器级中间件

express.Router 使用 express.Router 类创建模块化的、可安装的路由处理。路由实例是一个完整的中间件和路由系统。

你可以用中间件进行日志记录、身份验证等操作。如下所示,以记录用户的最新活动并解析身份验证标头,用它确定当前登录的用户并将其添加到 Request 对象。该函数在程序每次收到请求时执行。如果有错误,它会仅结束响应,而不会调用后续的中间件或路由处理。

var router = express.Router()//Load router-level middleware by using the router.use() and router.METHOD() functions.//The following example creates a router as a module, loads a middleware function in it,//   defines some routes, and mounts the router module on a path in the main app.var express = require(‘express’);var router = express.Router();// a middleware function with no mount path. This code is executed for//   every request to the router// loggingasync function logMiddleware (req, res, next) {    try {         console.log(req.user.id, new Date());     next();    } catch() {        res.status(500).send(error.message);    }}// authentication    async function checkAuthentication(req, res, next) => {// check header or url parameters or post parameters for tokenconst token = req.body.token || req.query.token || req.headers['x-access-token'] || req.headers['authorization'];      if (token) {        try {            // verifies secret            req.decoded = await jwt.verify(token, config.secret)            let checkUser = await authenticateTokenHelper.getUserDetail(req);            // if everything is good, save to request for use in other routes                if (checkUser) {                        req.user = req.decoded                        next()                } else {                    return res.status(403).json({                     message: responseMessage.noAuthorized                     })                }        } catch (err) {            return res.status(401).json({ message: responseMessage.invalidToken })        }  } else {    // if there is no token    return res.status(400).json({ message: responseMessage.invalidRequest })  }}router.use(logMiddleware);    router.get('/user, checkAuthentication, handler);

登录后复制

内置中间件

Express 有以下内置的中间件功能:

express.static 提供静态资源,例如 HTML 文件,图像等。express.json 负载解析用 JSON 传入的请求。express.urlencoded 解析传入的用 URL 编码的有效载荷请求。

错误处理中间件

错误处理中间件始终采用四个参数(err,req,res,next)。你必须通过提供四个参数来将其标识为错误处理中间件函数。即使你不需要使用 next 对象,也必须指定。否则 next 对象将被解释为常规中间件,并将会无法处理错误。基本签名如下所示:

app.use(function (err, req, res, next) {  console.error(err.stack)  res.status(500).send('Something broke!')})

登录后复制

例1:

app.get('/users', (req, res, next) => {  next(new Error('I am passing you an error!'));});app.use((err, req, res, next) => {  console.log(err);      if(!res.headersSent){    res.status(500).send(err.message);  }});

登录后复制

在这种情况下,管道末端的错误处理中间件将会处理该错误。你可能还会注意到,我检查了 res.headersSent 属性。这只是检查响应是否已经将标头发送到客户端。如果还没有,它将向客户端发送 HTTP 500  状态和错误消息。

例2:

你还可以链接错误处理中间件。通常以不同的方式处理不同类型的错误:

app.get('/users, (req, res, next) => {  let err = new Error('I couldn't find it.');  err.httpStatusCode = 404;  next(err);});app.get('/user, (req, res, next) => {  let err = new Error('I'm sorry, you can't do that, Dave.');  err.httpStatusCode = 304;  next(err);});app.use((err, req, res, next) => {   // handles not found errors  if (err.httpStatusCode === 404) {    res.status(400).render('NotFound');  }   // handles unauthorized errors   else if(err.httpStatusCode === 304){    res.status(304).render('Unauthorized');  }    // catch all   else if (!res.headersSent) {     res.status(err.httpStatusCode || 500).render('UnknownError');  }  next(err);});

登录后复制在这种情况下,中间件检查是否抛出了 404(not found)错误。如果是,它将渲染 “NotFound” 模板页面,然后将错误传递到中间件中的下一项。下一个中间件检查是否抛出了 304(unauthorized)错误。如果是,它将渲染“Unauthorized”页面,并将错误传递到管道中的下一个中间件。最后,“catch all” 错误处理仅记录错误,如果未发送响应,它将发送错误的 httpStatusCode(如果未提供则发送 HTTP 500 状态)并渲染 “UnknownError” 模板。

第三方级别的中间件

在某些情况下,我们将向后端添加一些额外的功能。先安装 Node.js 模块获取所需的功能,然后在应用级别或路由器级别将其加载到你的应用中。

示例:当 body-parser 处理 Content-Type 请求标头时,所有中间件都将使用解析的正文填充 req.body 属性。

const express = require('express');const bodyParser = require('body-parser');const app = express();app.use(bodyParser.urlencoded({extended:false}))app.use(bodyParser.json())app.post('/save',(req,res)=>{    res.json({        "status":true,         "payload":req.body    })}app.listen(3000,(req,res)=>{    console.log('server running on port')})

登录后复制

总结

中间件功能是一种非常好的方式,可以对每个请求或针对特定路由的每个请求运行代码,并对请求或响应数据采取措施。中间件是现代 Web 服务器的重要组成部分,并且非常有用。

更多编程相关知识,请访问:编程入门!!

以上就是Node.js 中间件的工作原理的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2725411.html

(0)
上一篇 2025年3月7日 23:22:51
下一篇 2025年2月19日 02:46:03

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Node.js 15正式版发布,将替代Node.js 14成为当前的的稳定发行版

    前两天,Node.js官方发布了Node.js 15的正式版本,Node.js 15 将替代 Node.js 14 成为当前的的稳定发行版,后者将在本月晚些时候升级为 LTS(长期支持)版本。如果大家想体验下Node.js 15 的最新功能…

    2025年3月7日
    200
  • 一些你可能不知道却有用的 Node.js 包

    本篇文章给大家推荐一些你可能不知道的,小众却有用的 node.js 包。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 视频教程推荐:nodejs 教程 yargs yargs 是一个用来处理命令行参数的包,可以帮你处理自…

    2025年3月7日
    200
  • 避免Node.js模块日志污染程序日志的方法介绍

    视频教程推荐:nodejs 教程 你是否有过这样的经历,当把 logging 添加到自定义 Node 模块中,并认为自己将会从这些额外信息中受益,却发现当你将模块添加为依赖项并运行 npm install 和 npm start 时,你的程…

    2025年3月7日 编程技术
    200
  • 3个值得收藏的实用nodejs软件包

    视频教程推荐:nodejs 教程 Node.js已成为IT不可或缺的一部分。有了自己的软件包管理器NPM,Node可以发现许多非常有用的库和框架。 在本文中,我将向您展示一些使用Node.js构建复杂动态应用程序的可能性。 1、Chalk:…

    2025年3月7日 编程技术
    200
  • 如何编写自己的虚拟DOM?方法介绍

    要构建自己的虚拟DOM,需要知道两件事。你甚至不需要深入 React 的源代码或者深入任何其他虚拟DOM实现的源代码,因为它们是如此庞大和复杂——但实际上,虚拟DOM的主要部分只需不到50行代码。 有两个概念: Virtual DOM 是真…

    2025年3月7日 编程技术
    200
  • node.js中怎么进行调试?

    相关推荐:《nodejs 教程》 用了几天node.js感觉很新奇,但是调试问题实在是愁煞人,开始的时候懒的学习调试方法,看看异常内容就可以了,但随着代码复杂程度的上升,并不是所有错误都是语法错误了,不调试搞不定了,只好搜搜资料,学习了一下…

    2025年3月7日 编程技术
    200
  • 浅析NodeJS中的Buffer

    相关推荐:《node js教程》 当年是看了朴灵的九浅一深 NodeJS 入门的 Node, 朴大大的书讲实践很少更多的篇幅用在了讲原理上,道理听了那么多,后来开始在前端工程领域使用 NodeJS 却处处掣肘,总结原因发现 NodeJS 中…

    2025年3月7日
    200
  • 了解NodeJS中的可读流

    相关推荐:《node js教程》 什么是可读流 可读流是生产数据用来供程序消费的流。我们常见的数据生产方式有读取磁盘文件、读取网络请求内容等,看一下前面介绍什么是流用的例子: const rs = fs.createReadStream(f…

    2025年3月7日
    200
  • Nodejs中什么是可写流?怎么使用

    相关推荐:《nodejs 教程》 什么是可写流 可写流是对数据流向设备的抽象,用来消费上游流过来的数据,通过可写流程序可以把数据写入设备,常见的是本地磁盘文件或者 TCP、HTTP 等网络响应。 看一个之前用过的例子 process.std…

    2025年3月7日
    200
  • 浅谈Nodejs中的​双工流

    相关推荐:《node js教程》 双工流就是同时实现了 Readable 和 Writable 的流,即可以作为上游生产数据,又可以作为下游消费数据,这样可以处于数据流动管道的中间部分,即 rs.pipe(rws1).pipe(rws2).…

    2025年3月7日
    200

发表回复

登录后才能评论