Node原生demo

1.=>创建配置模块,作用是先判断是开发环境还是生产环境,并将开发或生产环境的数据库信息和http信息分别筛开,便于选择

2.=>创建数据库模块,作用是连接数据库

3.=>创建路由模块,作用是供添加或查找路由

node_demo1过程记录

项目目录结构:
创建manager总项目目录
    ├ static ┬ index.html
             ├ css     ┬...
             ├ js      ┬...
             ├ upload  ┬...
             └ font    ┬...
    ├ libs   ┬ database.js  //连接数据库
             ├ http.js  //
             └ router.js    //路由
    ├config   ┬ config.dev.js   //开发配置
              ├ config.prod.js  //生产配置
              └ index.js
    ├
    ├package.json   //npm init -y  
    └server.js

 

config

开发环境  config.dev.js

const path = require('path');

module.exports={
    //database
    DB_HOST:'localhost',
    DB_PORT:3306,
    DB_USER:'root',
    DB_PASS:'',
    DB_NAME:'node_sql',

    //http
    HTTP_PORT:8520,
    HTTP_ROOT:path.resolve(__dirname,'../static'),
    HTTP_UPLOAD:path.resolve(__dirname,'../static/upload'),
}
View Code

生产环境  config.prod.js

module.exports={
    //database
    DB_HOST:'211.211.211.211',
    DB_PORT:3309,
    DB_USER:'root',
    DB_PASS:'123456',
    DB_NAME:'node_sql'
}
View Code

index.js

const process = require('process');   //process。当前进程的信息,当前程序的信息

// console.log(process.env);   //系统环境信息
// console.log(process.env.OS);    //当前系统内核

let mode = (process.env.OS=='Windows_NT'?'dev':'prod');
// 判断是开发环境或生产环境
// console.log(mode);

module.exports={
    mode,
    ...(mode=='dev'?require('./config.dev'):require('./config.prod'))
}
View Code

 

libs

数据库文件  database.js

const mysql = require('mysql');
const co = require('co-mysql');
const {DB_HOST,DB_PORT,DB_USER,DB_PASS,DB_NAME}=require('../config');

let conn = mysql.createPool({
    host:DB_HOST,
    port:DB_PORT,
    user:DB_USER,
    password:DB_PASS,
    database:DB_NAME,
});

module.exports=co(conn);
View Code

http.js

const http = require('http');   
const url = require('url'); 
const querystring = require('querystring');
const zlib = require('zlib');   //压缩请求
const fs =require('fs');    //读文件
const router = require('./router');     //路由
// const multiparty = require('multiparty');
const {Form} = require('multiparty');   //主要要用到multiparty里的Form
const {HTTP_PORT,HTTP_ROOT,HTTP_UPLOAD}=require('../config');

http.createServer((req,res)=>{
    res.setHeader('content-type','application/json');
    res.writeJson = function(json){
        res.write(JSON.stringify(json));
    }

    //1.先解析数据
    //2.再找路由
    
    //1.
    let {pathname,query}=url.parse(req.url,true);

    if(req.method=='POST'){
        if(req.headers['content-type'].startsWith('application/x-www-form-urlencoded')){
            //判断头,该处为普通的POST
            let arr=[];
            req.on('data',buffer=>{
                arr.push(buffer);
            });
            req.on('end',()=>{
                let post =querystring.parse(Buffer.concat(arr).toString());
                //2.
                handle(req.method,pathname,query,post,{});  //拿到post数据,文件数据为空
            })
        }else{
            //这是文件的POST
            let form = new Form({
                uploadDir:HTTP_UPLOAD   //这里是上传文件的地址,
            })
            form.parse(req);
            let post={};
            let files={};
            form.on('field',(name,value)=>{
                post[name]=value;
            });
            form.on('file',(name,file)=>{
                files[name]=file;
            })
            form.on('error',err=>{
                console.log(err);
            })
            form.on('close',()=>{
                //2.
                handle(req.method,pathname,query,post,files);
            })
        }
    }else{
        //2.
        handle(req.method,pathname,query,{},{});    //post和文件都为空
    }

    async function handle(method,url,get,post,files){
        let fn = router.findRouter(method,url);

        if(!fn){
            //文件请求
            let filepath = HTTP_ROOT+pathname;
            fs.stat(filepath,(err,stat)=>{
                if(err){
                    res.writeHeader(404);
                    res.write('NOT FOUND');
                    res.end();
                }else{
                    let rs=fs.createReadStream(filepath);
                    let gz=zlib.createGzip();
                    res.on('error',()=>{

                    })
                    res.setHeader('content-encoding','gzip');
                    rs.pipe(gz).pipe(res);
                }
            })
        }else{
            //接口
            try{
                await fn(res,get,post,files);
            }catch(e){
                res.writeHeader(500);
                res.write('Internal Server Error');
                res.end();
            }
        }
    }

}).listen(HTTP_PORT,()=>{
    console.log(`server ${HTTP_PORT} success`);
});
View Code

路由文件  router.js

//路由表
let router={};

function addRouter(method,url,fn){
    method = method.toLowerCase();
    url = url.toLowerCase();

    router[method] = router[method]||{};    //看method是否有东西,有则用,没有则新建一个
    router[method][url] = fn;
}

function findRouter(method,url){
    method = method.toLowerCase();
    url = url.toLowerCase();

    if(!router[method]||!router[method][url]){
        return null;    //找不到路由
    }else{
        return router[method][url];
    }
}

module.exports={
    addRouter,findRouter
};
View Code

 

Server.js

// const config = require('./config'); //它会自动找config目录下的index.js,因而index.js不用写
// const db = require('./libs/database');

// (async ()=>{
//     let data = await db.query('SELECT * FROM usertable');

//     console.log(data);
// })();
// // 上述代码主要是为了检查是开发环境或是生产环境,进而检查数据库是否连接成功

const db = require('./libs/database');
const http = require('./libs/http');
const {addRouter} = require('./libs/router');

addRouter('get','/list',async(res,get,post,files)=>{
    try{
        let data = await db.query(`SELECT * FROM usertable`);
        res.writeJson({error:0,data});
    }catch(e){
        res.writeJson({error:1,msg:'database error'});
    }

    let data=await db.query(`SELECT * FROM usertable`);
    res.writeJson({error:0,data});
    res.end();
});

addRouter('post','/add',async(res,get,post,files)=>{
    let {username,password,nickname}=post;
    if(!username||!password||!nickname){
        res.writeJ({error:1,msg:'params invaild'});
    }else{
        password=Number(password);
        if(isNaN(password)){
            res.writeJ({error:1,msg:'params invaild'});
            res.end();
        }else{
            try{
                // db.query(`INSERT INTO usertable (username,password,nickname) VALUES ('{$username}','{$password}','{$nickname}')`);
                //安全
                await db.query('INSERT INTO usertable (username,password,nickname) VALUES(?,?,?)',[username,password,nickname]);
                res.writeJson({error:0,msg:'success'})
            }catch(e){
                res.writeJson({error:1,msg:'database error'})
            }
        }
    }
    res.end();
});

addRouter('get','/del',async(res,get,post,files)=>{
    res.write(get['a']+get['b']);
    res.end();
});
View Code

 

 

 

 

 

 

posted @ 2019-11-05 00:03  Comedyy  阅读(259)  评论(0)    收藏  举报