• Node web 框架


     Express 框架是基于 http 做一个一个 web 框架

      

      具体做什么呢?

      1、对 request 、response 进行封装,实现了一些方便简洁的方法

      2、实现了 app.use 对 request 、response 进行处理

      3、实现了 get 、post 等方法实现路由返回响应值的值

      4、另外一些 render 等方法实现了使用模板引擎渲染页面

      下面使用了 200 行代码展示了 use / get / post 的实现

    const http = require('http')
    const regExpCompile = require('path-to-regexp')
    class Route {
        constructor(option) {
            // methods,path
            Object.assign(this, option)
            this.stack = []
    
        }
    
        addLayer(method, handle) {
            const layer = {
                method,
                handle,
            }
            this.stack.push(layer)
        }
    
        dispatch(req, res, next) {
            const {stack} = this;
            const match = false;
            const layer = null
            const {method} = req
            let id = 0
            let handle = null
    
            while (!handle && id < stack.length) {
                const layer = stack[id++]
                if (method.toLowerCase() === layer.method) {
                    handle = layer.handle
                    continue
                }
            }
            if (!handle) next && next()
            handle(req, res, next)
        }
    }
    class Layer {
        constructor(option, fn) {
            // path,name,regexp
            Object.assign(this, option)
            this.handle = fn
        }
    }
    class Router {
        constructor() {
            this.stack = []
        }
    
        use(path, fn) {
            const layer = new Layer({
                path,
                use: true,
                regexp: regExpCompile(path, []),
            }, fn)
            layer.route = null
            this.stack.push(layer)
        }
    
        route(path, fn, methods = []) {
            const route = new Route({
                path
            })
            methods.forEach(item => {
                route.addLayer(item, fn)
            })
            const layer = new Layer({
                path,
                regexp: regExpCompile(path, []),
            }, route.dispatch.bind(route))
            layer.route = route
            this.stack.push(layer)
        }
    
        handle(req, res, callback) {
            const {url} = req
            const {stack} = this
            let idx = 0
    
            next()
    
            function next() {
                let match = false
                let route = null
                let layer = null
                while (!match && idx < stack.length) {
                    layer = stack[idx++]
                    match = layer.regexp.exec(url)
                    if (layer.use) match = true
                    route = layer.route
                    if (!match) continue
                    if (!route) continue
                }
                if (!match) {
                    callback && callback()
                    return
                }
                layer.handle(req, res, next)
            }
        }
    
    }
    const app = {
        use: function (fn) {
            let router = this._router
            if (!router) {
                router = new Router()
                this._router = router
            }
            let path = '/'
            if (typeof fn !== 'function') {
                path = fn
                fn = arguments[1]
            }
            router.use(path, fn)
    
        },
        get: function (fn) {
            let router = this._router
            if (!router) {
                router = new Router()
                this._router = router
            }
            let path = '/'
            if (typeof fn !== 'function') {
                path = fn
                fn = arguments[1]
            }
            router.route(path, fn, ['get'])
        },
        post: function (fn) {
            let router = this._router
            if (!router) {
                router = new Router()
                this._router = router
            }
            let path = '/'
            if (typeof fn !== 'function') {
                path = fn
                fn = arguments[1]
            }
            router.route(path, fn, ['post'])
        },
        all: function () {
    
        },
        listen: function () {
            const _this = this
    
            const server = http.createServer(function (req, res) {
                _this._router.handle(req, res)
            })
            server.listen.apply(server, arguments)
        }
    }
    app.use((req, res, next) => {
        req.test = 'test1'
        next()
    })
    app.use((req, res, next) => {
        req.test2 = 'test2'
        next()
    })
    app.get('/', (req, res) => {
        const tst = req.test
        const tst2 = req.test2
        res.end('/' + tst + tst2)
    })
    app.get('/get', (req, res) => {
        const tst = req.test
        const tst2 = req.test2
        res.end('get' + tst + tst2)
    })
    app.get('/test', (req, res) => {
        const tst = req.test
        const tst2 = req.test2
        res.end('test' + tst + tst2)
    })
    app.listen(3300)
    

      

      代码仅供研究!

     博客园小结巴巴: https://www.cnblogs.com/jiebba

  • 相关阅读:
    C#如何生成CHM帮助文件
    使用WebBrowser控件播放Flash网页相关问题解决方法
    C# AnimateWindow与WindowState同时使用的效果
    C#读取计算机串口
    C#基础概念二十五个问题
    C# ini 文件读取方法
    JSP读出MYSQL数据库时的乱码问题解决方案
    世界编程大赛头名程序
    比较著名的.net技术论坛网址(含国外的)
    How to Install Linux, Apache, MySQL, PHP (LAMP) stack on CentOS 6
  • 原文地址:https://www.cnblogs.com/jiebba/p/12779783.html
Copyright © 2020-2023  润新知