写一个类似express框架

2023-10-08 22:39:40发布
13

express.js

const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
 
let G = {
 
    _get: {},
 
    _post: {},
 
    //扩展res方法
    extendRes(res){
        res.send=(data)=>{
            res.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' });
            if(typeof data === 'object'){
                data = JSON.stringify(data);
            }
            res.end(data);
        }
    },
 
    //读取静态文件函数
    initStatic(staticPath, req, res) {
 
        //获取访问路径
        let pathName = url.parse(req.url).pathname;
 
        //如果访问路径是 / ,则把访问路径设置为index.html
        pathName = (pathName == '/' ? '/index.html' : pathName);
        try {
            let data = fs.readFileSync(staticPath + pathName);
            if (data) {
                let type = G.getFileMime(path.extname(pathName));
                res.writeHead(200, { 'Content-Type': type + ';charset="utf-8"' });
                res.end(data);
            }
        } catch (error) {
 
        }
    },
 
    /*
        判断文件格式
        suffix的参数是一个文件的后缀名。比如 :.html、.css
    */
    getFileMime(suffix) {
        let data = fs.readFileSync('./data/mime.json');
        return JSON.parse(data.toString())[suffix]
 
    },
 
    //创建服务器方法
    createServer() {
        return http.createServer((req, res) => {
            if (req.url === '/favicon.ico') { return; }
 
            G.extendRes(res);
 
            G.initStatic(express.staticPath, req, res);
            
            //获取请求方式 
            let method = req.method.toLowerCase();
 
            //路由,先判断G是否有相应的注册方法,然后判断method是get还是post,分别执行不同的操作
            if (G['_' + method][url.parse(req.url).pathname]) 
            {
                if(method == 'get')
                {
                    //把前端传过来的参数保存在query上
                    req.query = url.parse(req.url).query;
 
                    G['_' + method][url.parse(req.url).pathname](req, res);
                }
                else if(method == 'post')
                {
                    let str = '';
                    req.on('data',(data)=>{
                        str+=data;
                    });
                    req.on('end', ()=>{
                        //把前端传过来的参数保存在body上
                        req.body = str;
 
                        G['_' + method][url.parse(req.url).pathname](req, res);
                    });
                }  
            }
            //如果是访问的是静态页面,G['_' + method][req.url] == undefined。也会执行这里。但是读取静态文件的时候,已经res.end了,后面就算执行res.write或者res.end都没用。因为流已经关闭了。
            else 
            { 
                res.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
                res.end('页面不存在');
            }
        });
    }
 
};
 
class Express {
 
    staticPath = 'www';
 
    //监听端口方法
    listen(port) {
        G.createServer().listen(port);
    }
 
    //修改静态资源的访问路径
    static(staticPath) {
        this.staticPath = staticPath;
    }
 
    //注册get方法
    get(str, callback) {
        G._get[str] = callback;
    }
 
    //注册post方法
    post(str, callback) {
        G._post[str] = callback;
    }
}
 
const express = new Express();
 
module.exports = () => {
    return express;
};

使用案列

const express = require('./model/express');
 
let server = express();
server.listen(3000);
 
//静态文件目录
server.static('./static');
 
server.get('/news', (req,res)=>{
    //获取get参数
    console.log(req.query);
    res.send({news : 'xxx事件'});
});
 
server.post('/login',(req,res)=>{
    //获取post参数
    console.log(req.body);
    res.send(({score : 90}));
});
 
server.get('/list', (req,res)=>{
    res.send('list');
});
 
console.log('server is running at : http://localhost:3000');


项目下载地址 : https://download.csdn.net/download/QQ408896436/12651626