• 【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--自动路由篇(1/8)【route】


    文章目录

    前情概要

    在使用express框架开发的时候,每加一个请求,都在增加一条route请求规则,类似于下面的代码,很烦有木有!

    app.use('/myroute path', (req, res, next) ⇒ { //dosomething }) 我们难道不能再智能一点点么,学习后端mvc框架一样,比如加个标记,或者默认规则直接自动映射嘛。约定胜于配置嘛!

    我们的实现思路

    1. 拦截所有请求
    2. 根据我们的规则进行路由的匹配
    3. 调用匹配到的处理函数

    拦截所有请求

    这个太好办了,app.use('/') 搞定。参考下面的代码

    import * as express from 'express'
    import * as controllers from './controller'
    import { RequestHandler, RouteHandler } from 'gd-express-basic'
    
    const _app = express();
    //第一个express 中间件,处理一下跨域请求中的options请求。
    _app.use((req, res, next) => {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With');
        res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS');
        if (req.method == 'OPTIONS') {
            res.send(new ResponseBase(200));
        }
        next && next();
    });
    //第二个中间件,拦截所有请求对路由做自动映射
    RouteHandler(_app, controllers);
    //第三个中间件,处理请求
    _app.use(RequestHandler);
    //第N个中间件,处理一下error呀,404呀等其他情况。
    

    根据规则进行路由的匹配

    接下来看一看RouteHandler方法。主要干几个事情

    1. 缓存所有action,方便后续的调用。【 请求处理函数的特性注册篇【详细说明】
    2. 拦截所有请求,并根据规则解析到对应的action上面去。【app.use('/', (req, res, next)】
    3. 根据解析出来的controller 、action名称以及当前请求的method找到对应的action并记录到当前请求对象上,方便接下来的请求处理。 目前我们的规则很简单。url分2层,第一层为controller名称,第二层为action名称。即://;
    /**
     * 路由选择处理中间件
     * 
     * @export
     * @param {core.Express} app 
     * @param {*} controllers 
     */
    export function RouteHandler(app: core.Express, controllers: any) {
       //程序启动的时候,找到当前所有的controllers,并根据规则缓存好我们所有的处理函数(action),方便接下来的匹配
       //请求处理函数发现篇【controller+action】具体讲到
        find(controllers)
    //拦截所有请求,对请求
        app.use('/', (req, res, next) => {
        //拿到route并解析出来controller和action的名称。
            var pathArr = getRouteTokens(req.path)
            var controller = (pathArr[0] && pathArr[0].toLowerCase()) || 'home';
            var action = (pathArr[1] && pathArr[1].toLowerCase()) || 'index'
            //根据参数找到能处理这个请求的action
            var desc = GetActionDescriptor(controller, action, req.method)
            if (!desc) {
                desc = GetActionDescriptor(controller, '_default', req.method)
            }
            if (desc && (!desc.HttpMethod || (desc.HttpMethod && desc.HttpMethod === req.method))) {
    
                res.locals.authInfo = { isAuth: desc.isAuth };
                //如果请求能匹配到可以处理的action,则赋值
                res.locals.actionDescriptor = desc;
            }else{//否则跳过。当然在这里也可以直接返回404,结束本次请求。
             }
            next && next()
        })
    }
    
    function getRouteTokens(path: string) {
        var pathArr = path.split('/');
        var arr: string[] = [];
        pathArr.forEach(element => {
            if (element) arr.push(element)
        });
        return arr
    }
    

    代码那是相当的简单。其实只干了一件事情,据我们的url规则找到与之匹配的在项目启动的时候扫描缓存的请求处理函数

    1. 考虑到前端不太会有area的概念,所以暂时没有支持,如果要支持其实也很简单,增加一个area注册,然后再做路由匹配的时候多判断一次area就完事儿了。
    2. 估计也不太会有自定义route 的要求,比如dotnet mvc 里面的【[Route("/path")]】特性。所以也暂未做支持。如果确实有也可以通过app.use实现。
  • 相关阅读:
    [改善Java代码]在equals中使用getClass进行类型判断
    [改善Java代码]equals应该考虑null值的情景
    [改善Java代码]覆写equals方法时不要识别不出自己
    [改善Java代码] 推荐使用序列化实现对象的拷贝
    [改善Java代码]避免对象的浅拷贝
    [改善Java代码]让工具类不可实例化
    [改善Java代码]建议40:匿名类的构造函数很特殊
    [改善Java代码]使用匿名类的构造函数
    [改善Java代码]使用静态内部类提高封装性
    [改善Java代码]构造函数尽量简化
  • 原文地址:https://www.cnblogs.com/calvinK/p/nodejs-mvc-route-auto-match.html
Copyright © 2020-2023  润新知