当前位置 博文首页 > 文章内容

    express中的中间件

    作者: 栏目:未分类 时间:2020-07-13 9:00:50

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    中间件的几个重要特性:

    1. 中间件必须是函数

      // 情况一
      app.use(static) // static必须是函数
      
      // 情况二
      app.use(static()) // static的返回值必须是函数
      
    2. 表示所有路由

      // 省略路由字符串参数
      app.use(中间件)
      
      // '/*'
      app.use('/*', 中间件)
      
    3. 顺序:再express4.0中,根据路由条件是否满足,中间件和路由时从上到下,一个一个执行。而在express4.0之前,必须显示的把路由连起来。

    4. 如果一个中间件既不使用next()使路由跳转到下一个中间件,也不响应数据给客户端,请求就会挂起,导致超时

    5. 在前面的例子中,我们的中间件会用语句return next()提前终止。Express不期望中间件返回值(并且它不会用返回值做任何事情),所以这只是缩短了的next(); return

      目前就知道 return next() 等效于 next()。至于还有什么别的功能还不清楚
      

    路由中间件

            app.use(function(req, res, next){  // 0
                  console.log('\n\nALLWAYS');
                  next();
            });
            app.get('/a', function(req, res){  // 1
                  console.log('/a: 路由终止’);
                  res.send('a');
            });  
            app.get('/a', function(req, res){  // 2
                  console.log('/a: 永远不会调用’);
            });
            app.get('/b', function(req, res, next){  // 3
                  console.log('/b: 路由未终止’);
                  next();
            });
            app.use(function(req, res, next){  // 4
                  console.log('SOMETIMES');
                  next();
            });
            app.get('/b', function(req, res, next){  // 5
                  console.log('/b (part 2): 抛出错误’ );
                  throw new Error('b失败’);
            });
            app.use('/b', function(err, req, res, next){  // 6
                  console.log('/b检测到错误并传递’);
                  next(err);
            });
            app.get('/c', function(err, req){  // 7
                  console.log('/c: 抛出错误’);
                  throw new Error('c失败’);
            });
            app.use('/c', function(err, req, res, next){  // 8
                  console.log('/c: 检测到错误但不传递’);
                  next();
            });
            app.use(function(err, req, res, next){  // 9
                  console.log(’检测到未处理的错误: ' + err.message);
                  res.send('500- 服务器错误’);
            });
            app.use(function(req, res){  // 10
                  console.log(’未处理的路由’);
                  res.send('404- 未找到’);
            });
            app.listen(3000, function(){  // 11
                  console.log(’监听端口3000');
            });
    

    访问/a的路由后台打印结果:会执行 0 和 1, 2不会执行。因为1已经响应数据给客户端了

    image-20200711174845579

    访问/b: 会执行3 、4、5、6、9。 这里的throw new Error('b失败’)就相当于next(),将请求传递给下一个路由中间件,并且通过err可以捕获到抛出的错误

    image-20200711175242201

    访问/c: 会执行7、8、10。注意这里不会执行9,因为在步骤8的时候并没有将搓搓传到下一个路由中间件,路由就不会到到9,而是直接到10了。

    疑问:手动抛出错误跟服务本身出错有什么区别,服务器本身出错就会直接到抛出错误的路由。另外还可以手动定制500页面-也就是说,即使服务器出错也可以返回一定的页面给用户

    自定义中间件

    // /lib/tourRequiresWaiver.js
    
    module.exports = {
      tourRequiresWaiver: function(req, res, next){
        res.type('text/plain')
        next();
      }
    }
    
    // 入口文件
    
    const middleWaire = require('./lib/tourRequiresWaiver')
    ...
    // 自定义中间件  --所有在它后面出现的路由都会调用这个中间件
    app.use(middleWaire.tourRequiresWaiver)