express源码实现2——中间件实现

上一篇内容

实现express中最主要的方法——创建服务器,监听端口,接收各种前端请求。

中间件是什么

  1. 中间件就是在路由过程中起过渡作用,用以检查权限,检查是否合法,最后再进入我们真正的路由
  2. 中间件有next方法,可以决定是否继续执行 如果调用next方法表示继续执行
  3. 中间件也可以匹配路径 只要路径开头匹配即可,默认是/等同于不写。比如中间件的/add可以匹配请求路径的/add/user
  4. 中间件中的req和res 和路由中的是同一个
  5. 一个页面中可以有多个中间件

    本篇文章的目的

    实现express中间件的源码

    思路

    之前路由的判断原理是将前端发送来的每个请求与路由池里保存的请求匹配,匹配上就执行相应回调函数。现在加入中间件,由于中间件不调用next()方法会阻塞接下来中间件/路由的执行,所以采用的原理是:讲中间件放入路由池,每当接收到前端请求,依次遍历路由池中的值,判断是中间件还是路由,分别处理。

流程

  1. 定义中间件函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    app.use=function (path,fn) {
    //当只传递回调函数不传递路径时
    if (typeof fn !='function') {
    fn=path;
    path='/';
    }
    var config={method:'middleware',path:path,fn:fn}
    app.routes.push(config);
    }
  2. 定义中间件的next方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    function express () {
    //首先在express函数上部定义一个索引
    var index=0;
    //执行一次next
    next();
    function next () {
    //判断是否遍历完都没有匹配到
    if (index>=app.routes.length) {
    res.end(`Cannot ${method} ${pathname}`)
    }
    //遍历到的路由项
    var route=app.routes[index++];
    //如果是中间件
    if (route.method=='middleware') {
    /**判断路径是否匹配
    *第一项匹配所有路径
    *第二项与请求路径完全匹配
    *第三项模糊匹配
    **/
    if (route.path=='/'||route.path==pathname||pathname.startsWith(route.path+'/')) {
    //匹配成功,执行中间件回调函数
    route.fn(req,res,next);
    } else {
    //没匹配到,进行下一次遍历
    next();
    }
    //如果是路由
    } else {
    //判断路由是否匹配
    if ((route.method==method||route.method=='all')&&(route.path==pathname||route.pathname=='*')) {
    //路由匹配成功
    route.fn(req,res);
    } else {
    //没匹配到,进行下次遍历
    next();
    }
    }
    }
    }