写一个类似express框架

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;
};

server.js

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值