• 技术文章 >web前端 >js教程

    Node.js 中间件的工作原理

    青灯夜游青灯夜游2020-10-22 19:51:21转载549

    视频教程推荐:node js教程

    什么是 Express 中间件?

    编写 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 init
    npm install express --save
    
    Create 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 Handlers
    app.get('/user/:id', userMiddleware, userController);

    中间件链

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

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

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

    2.png

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

    Express中间件的类型

    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
    // logging
    async 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 token
    const 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 有以下内置的中间件功能:

    错误处理中间件

    错误处理中间件始终采用四个参数(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);
    });

    第三方级别的中间件

    在某些情况下,我们将向后端添加一些额外的功能。先安装 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 中间件的工作原理的详细内容,更多请关注php中文网其它相关文章!

    本文转载于:thirdrocktechkno,如有侵犯,请联系a@php.cn删除
    专题推荐:Node.js 中间件
    上一篇:深入了解Node.js 中的多线程和多进程 下一篇:32个纯手写JS,巩固你的JS基础
    第14期线上培训班

    相关文章推荐

    • nodejs接口如何传输数据?• 使用Node.js+Chrome+Puppeteer实现网站的爬取• 通过Node+Redi实现API速率限制• 浅谈 Node.js 中间件的工作原理• 浅谈Node.js中require()的工作原理

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网