搜索

有思俱乐部学习园地

Node.js 实现路由

可从git.1473.cn查看源码

搭建http服务器

const http = require('http');
const url = require('url');
//启动服务
app.listen = (port, host, callback) => {
    http.createServer((req, res) => {
        // 获取请求的方法
        const method = req.method.toLowerCase()
        // 解析url
        const urlObj = url.parse(req.url, true)
        // 获取path部分
        const pathName = urlObj.pathname
        // 获取后缀
        const ext = path.extname(pathName).slice(1);
        // 若有后缀 则是静态文件
        if (ext) {
            handleStatic(res, _static + pathName, ext) // 详见 下一章 实现目录浏览功能
        } else {
            // 遍历路由池
            passRouter(app.routes, method, pathName)(req, res) // 具体实现在下面
        }
    }).listen(port, host, ()=>{
        console.log(`server start at http://${host}:${port}`)
    });
};
app.listen('8100', 'localhost')

实现路由

实现路由池

const app = {};
app.routes = [];
let _static = '.';
// 命令集合
const methods = ['get', 'post', 'put', 'delete', 'options', 'all', 'use'];
// 实现路由池
methods.forEach((method) => {
    app[method] = (path, fn) => {
        app.routes.push({method, path, fn});
    }
});

遍历路由池

// 使用generator函数实现惰性求值
const lazy = function* (arr) {
    yield* arr;
}

// routes 路由池
// method 命令
// path 请求路径
const passRouter = (routes, method, path) => (req, res) => {
    const lazyRoutes = lazy(routes);
    (function next() {
        // 当前遍历状态
        const it = lazyRoutes.next().value;
        if (!it) {
            // 已经遍历了所有路由 停止遍历
            res.end(`Cannot ${method} ${path}`);
            return;
        } else if (it.method === 'use' && (it.path === '/' || it.path === path || path.startsWith(it.path.concat('/')))) {
            // 匹配到中间件
            it.fn(req, res, next);
        } else if ((it.method === method || it.method === 'all') && (it.path === path || it.path === "*")) {
            // 匹配到路由
            it.fn(req, res);
        } else {
            // 继续匹配
            next();
        }
    })()
}

工作人员

 
        
作者:郑子民
信息录入:郑子民