前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Node.js商品管理小实战

Node.js商品管理小实战

作者头像
切图仔
发布2022-09-14 15:07:38
1.1K0
发布2022-09-14 15:07:38
举报
文章被收录于专栏:生如夏花绚烂

1.目录结构

config:配置文件,这里我们写了两套配置 开发环境和生产环境,其中index.js为配置文件入口,根据不同的环境返回不同的配置 config/index.js

代码语言:javascript
复制
const process=require('process');//当前程序信息

let mode=(process.env.OS=='Windows_NT'?'dev':'prod');//当前环境

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

在server.js引用并打印

代码语言:javascript
复制
const config = require('./config')
console.log(config)
代码语言:javascript
复制
{
  mode: 'dev',
  DB_HOST: 'localhost',
  DB_PORT: 3306,
  DB_USER: 'root',
  DB_PASS: '',
  DB_NAME: '20181101',
  HTTP_PORT: 8080,
  HTTP_ROOT: 'C:\\Users\\21974\\Desktop\\nodejs\\manager\\static',
  HTTP_UPLOAD: 'C:\\Users\\21974\\Desktop\\nodejs\\manager\\static\\upload'
}

libs分离出来的模块如数据库,请求等 static存放静态文件

2.测试数据库连接 引入mysql,co-mysql模块 cnpm i mysql cnpm i co-mysql 在libs/database.js

代码语言:javascript
复制
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)

在server.js

代码语言:javascript
复制
const config = require('./config')
const db = require('./libs/database')
;(async ()=>{
  let data = await db.query('select * from item_table')
  console.log(data)
})()
//返回测试数据
[
  RowDataPacket { id: 3, title: 'test3', price: 23, count: 1 },
  RowDataPacket { id: 2, title: 'test2', price: 100, count: 2 }
]

3.初始化路由模块 在libs/router.js

代码语言:javascript
复制
//路由表
let router = {};
function addRouter(method,url,fn) {
    method = method.toLowerCase();
    url = url.toLowerCase();
    router[method] = router[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
}

router对象存放路由及路由对应的方法如

代码语言:javascript
复制
{
    get:{
        '/a':function(){}
    }
}

addRouter添加路由

findRouter找路由\

4.初始化http模块

在libs/http.js

代码语言:javascript
复制
const http = require('http');
const url = require('url');
const querystring=require('querystring');
const zlib = require('zlib');
const fs = require('fs');
const {Form} = require('multiparty');
const {HTTP_PORT,HTTP_ROOT,HTTP_UPLOAD} = require('../config')
const router = require('./router')

http.createServer((req,res)=>{
    //解析数据
    let {pathname,query} = url.parse(req.url)
    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))
            });
            //找路由
            handle(req.method,pathname,query,post,{})

        }else{
            //文件post
            let form = new Form({
                uploadDir:HTTP_UPLOAD
            });
            form.parse(req)
            let post = {}
            let files = {}
            //普通文本
            form.on('file',(name,value)=>{
                post[name]=value;
            });
            //文件
            form.on('file',(name,files)=>{
                files[name] =value
            })
            //处理异常
            form.on('error',(e)=>{
                console.log(e)
            })
            form.on('close',()=>{
                //找路由
                handle(req.method,pathname,query,post,files)
            })
        }
    }else{
        //找路由(GET)
        handle(req.method,pathname,query,{},{})
    }
  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();
                    rs.on('error',()=>{

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

}).listen(HTTP_PORT);
console.log('server start')

在浏览器输入http://127.0.0.1:3000/index.html返回静态页面

测试接口 server.js

代码语言:javascript
复制
const db = require('./libs/database');
const http = require('./libs/http');
const {addRouter} = require('./libs/router');
//添加路由
addRouter('get','/aaa', async (res,get,post,files)=>{
  res.write('aaa');
  res.end();
});

浏览器输入/aaa返回aaa 到此测试完毕 开发部分接口

代码语言:javascript
复制
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 item_table`);
    res.writeJson({
      error:0,
      data
    });
  }catch(e){
    res.writeJson({error:1,msg:'databse error'});
  }
  res.end();
  
  // res.write()
  res.end();
});
//商品添加
addRouter('get','/add', async (res,get,post,files)=>{
  let {title,price,count} = post;
  if(!title||!price||!count){
   res.writeJson({error:1,msg:'params invalid'}); 
   res.end();
  }else{
    price = Number(price);
    count = Number(count);
    if(isNaN(price) || isNaN(count)){
      res.writeJson({error:1,msg:'params invalid'}); 
      res.end();
    }else{
      // db.query(`inert into item_table(title,price,count) values('${title}',${price},${count})`)sql注入风险
      try{
        await db.query('insert into item_table (title,price,count) values(?,?,?)',[title,price,count]);
        res.writeJson({error:0,msg:'success'});

      }catch(e){
        res.writeJson({error:0,msg:'error'});
      }
      res.end();
    }
  }

});
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档