Node.js Express+Mongodb 项目实战
Posted 土豆儿哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js Express+Mongodb 项目实战相关的知识,希望对你有一定的参考价值。
Node.js Express+Mongodb 项目实战
这是一个简单的商品管理系统的小项目,包含的功能还算挺全的,项目涵盖了登录、注册,图片上传以及对商品进行增、删、查、改等操作,对于新手来说是个很不错的练手项目,分享给大家。
GitHub源码:https://github.com/oceanMin/cms
项目前准备
- 安装node.js
- 安装express
- 安装mongoDB
章节目录
商品管理系统目录结构:
查询mongodb数据库登录功能
创建数据库
1.打开数据库
2.需要创建productmanage
数据库
3.productmanage
数据库里面有user表
4.在user
表中有数据 ,如果没有执行如下命令插入
db.user.insert({"username":"admin","password":"123456"})
如图:
连接数据库
继续在app.js文件中添加如下代码:
//安装body-parser中间件 //获取post var bodyParser = require(\'body-parser\'); // 设置body-parser中间件 app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); //数据库操作 var MongoClient=require(\'mongodb\').MongoClient; var DbUrl=\'mongodb://localhost:27017/productmanage\'; /*连接数据库*/ //登录 app.get(\'/login\',function(req,res){ res.render(\'login\'); }) //获取登录提交的数据 app.post(\'/doLogin\',function(req,res){ //1.获取数据 //2.连接数据库查询数据 MongoClient.connect(DbUrl,function(err,db){ if(err){ console.log(err); return; } //查询数据 {"username":req.body.username,"password":req.body.password} var result=db.collection(\'user\').find(req.body); //遍历数据的方法 result.toArray(function(err,data){ console.log(data); if(data.length>0){ console.log(\'登录成功\'); //保存用户信息 req.session.userinfo=data[0]; res.redirect(\'/product\'); /*登录成功跳转到商品列表*/ }else{ //console.log(\'登录失败\'); res.send("<script>alert(\'登录失败\');location.href=\'/login\'</script>"); } db.close(); }) }) })
退出登录
退出登录很简单,下面一段代码搞定:
app.get(\'/loginOut\',function(req,res){ //销毁session req.session.destroy(function(err){ if(err){ console.log(err); }else{ res.redirect(\'/login\'); } }) })
中间件权限判断
这里我们要添加一个中间件作为权限判断,首先要安装一个express-session
中间件用来保存用户信息
cnpm install express-session --save-dev
在app.js文件中,我们自定义一个中间件用来判断登录状态
//保存用户信息 var session = require("express-session"); //配置中间件 固定格式 app.use(session({ secret: \'keyboard cat\', resave: false, saveUninitialized: true, cookie: { maxAge:1000*60*30 }, rolling:true })) //自定义中间件 判断登录状态 app.use(function(req,res,next){ //console.log(req.url); //next(); if(req.url==\'/login\' || req.url==\'/doLogin\'){ next(); }else{ if(req.session.userinfo&&req.session.userinfo.username!=\'\'){ /*判断有没有登录*/ app.locals[\'userinfo\']=req.session.userinfo; /*配置全局变量 可以在任何模板里面使用*/ next(); }else{ res.redirect(\'/login\') } } })
密码加密存储
这里我们用到的是md5
加密,用法很简单,还是一样 先安装依赖:
cnpm install md5-node --save-dev
在app.js
文件中引入:
var md5=require(\'md5-node\'); /*md5加密*/ //获取登录提交的数据 app.post(\'/doLogin\',function(req,res){ var username=req.body.username; var password=md5(req.body.password); /*要对用户输入的密码加密*/ //1.获取数据 //2.连接数据库查询数据 MongoClient.connect(DbUrl,function(err,db){ if(err){ console.log(err); return; } //查询数据 {"username":req.body.username,"password":req.body.password} var result=db.collection(\'user\').find({ username:username, password:password }); //另一种遍历数据的方法 result.toArray(function(err,data){ if(data.length>0){ console.log(\'登录成功\'); //保存用户信息 req.session.userinfo=data[0]; res.redirect(\'/product\'); /*登录成功跳转到商品列表*/ }else{ //console.log(\'登录失败\'); res.send("<script>alert(\'登录失败\');location.href=\'/login\'</script>"); } db.close(); }) }) })
※ 注意:在使用md5加密登录系统时,要确保数据库中保存的密码是加密的,否则会因密码不一致而登录不上。
数据库商品列表显示
打开app.js
文件,修改代码如下:
app.get(\'/product\',function(req,res){ //连接数据库查询数据 MongoClient.connect(DbUrl,function(err,db){ if(err){ console.log(err); console.log(\'数据库连接失败\'); return; } var result=db.collection(\'product\').find(); result.toArray(function(error,data){ if(error){ console.log(error); return; } db.close(); //console.log(data); res.render(\'product\',{ list:data }); }) }) })
DB数据库的封装
完善DB数据库封装。新建 modules/db.js
,添加如下代码:
var MongoClient = require(\'mongodb\').MongoClient; var DbUrl = \'mongodb://127.0.0.1:27017/productmanage\'; //连接数据库 var ObjectID = require(\'mongodb\').ObjectID; function __connectDb(callback){ MongoClient.connect(DbUrl, function(err,db){ if(err){ console.log(err); console.log(\'数据库连接失败\'); return; } callback(db); }) } //暴露ObjectID exports.ObjectID = ObjectID; /** * collectionname: 表名 * json:查询条件 * callback: 返回查询的数据 */ // 查询数据 exports.find = function(collectionname,json,callback){ __connectDb(function(db){ var result = db.collection(collectionname).find(json); result.toArray(function(error, data){ db.close(); /**关闭数据库连接 */ callback(error, data); /**拿到数据,执行回调函数 */ }) }) } // 新增数据 exports.insert = function(collectionname,json,callback){ __connectDb(function(db){ db.collection(collectionname).insertOne(json,function(error,data){ callback(error,data); }) }) } // 修改数据 exports.update = function(collectionname,json1,json2,callback){ __connectDb(function(db){ db.collection(collectionname).updateOne(json1,{$set:json2},function(error,data){ callback(error,data); }) }) } // 删除数据 exports.delete = function(collectionname,json,callback){ __connectDb(function(db){ db.collection(collectionname).deleteOne(json,function(error,data){ callback(error,data); }) }) }
然后在app.js
文件中引入db.js文件
//数据库操作 var DB=require(\'./modules/db.js\'); //获取登录提交的数据 app.post(\'/doLogin\',function(req,res){ var username=req.body.username; var password=md5(req.body.password); /*要对用户输入的密码加密*/ //1.获取数据 //2.连接数据库查询数据 DB.find(\'user\',{ username:username, password:password },function(err,data){ if(data.length>0){ console.log(\'登录成功\'); //保存用户信息 req.session.userinfo=data[0]; res.redirect(\'/product\'); /*登录成功跳转到商品列表*/ }else{ //console.log(\'登录失败\'); res.send("<script>alert(\'登录失败\');location.href=\'/login\'</script>"); } }) }) //商品列表 app.get(\'/product\',function(req,res){ DB.find(\'product\',{},function(err,data){ res.render(\'product\',{ list:data }); }) })
图片上传
图片上传插件的使用
1. npm install multiparty
2. var multiparty = require(\'multiparty\');
3.上传图片的地方
var form = new multiparty.Form(); form.uploadDir=\'upload\' 上传图片保存的地址 form.parse(req, function(err, fields, files) { //获取提交的数据以及图片上传成功返回的图片信息 });
4.html页面form 表单要加入 enctype="multipart/form-data"(这个很重要)
图片上传代码如下:
var multiparty = require(\'multiparty\'); /*图片上传模块 即可以获取form表单的数据 也可以实现上传图片*/ //获取表单提交的数据 以及post过来的图片 app.post(\'/doProductAdd\',function(req,res){ //获取表单的数据 以及post过来的图片 var form = new multiparty.Form(); form.uploadDir=\'upload\' //上传图片保存的地址 目录必须存在 form.parse(req, function(err, fields, files) { //获取提交的数据以及图片上传成功返回的图片信息 //console.log(fields); /*获取表单的数据*/ //console.log(files); /*图片上传成功返回的信息*/ var title=fields.title[0]; var price=fields.price[0]; var fee=fields.fee[0]; var description=fields.description[0]; var pic=files.pic[0].path; //console.log(pic); DB.insert(\'product\',{ title:title, price:price, fee, description, pic },function(err,data){ if(!err){ res.redirect(\'/product\'); /*上传成功跳转到首页*/ } }) }); })
修改商品
修改商品代码如下:
//执行修改的路由 app.post(\'/doProductEdit\',function(req,res){ var form = new multiparty.Form(); form.uploadDir=\'upload\' // 上传图片保存的地址 form.parse(req, function(err, fields, files) { //获取提交的数据以及图片上传成功返回的图片信息 var _id=fields._id[0]; /*修改的条件*/ var title=fields.title[0]; var price=fields.price[0]; var fee=fields.fee[0]; var description=fields.description[0]; var originalFilename=files.pic[0].originalFilename; var pic=files.pic[0].path; if(originalFilename){ /*修改了图片*/ var setData={ title, price, fee, description, pic }; }else{ /*没有修改图片*/ var setData={ title, price, fee, description }; //删除生成的临时文件 fs.unlink(pic); } DB.update(\'product\',{"_id":new DB.ObjectID(_id)},setData,function(err,data){ if(!err){ res.redirect(\'/product\'); } }) });
删除商品数据
app.js加入删除商品代码:
//删除商品 app.get(\'/productdelete\',function(req,res){ //获取id var id=req.query.id; DB.deleteOne(\'product\',{"_id":new DB.ObjectID(id)},function(err){ if(!err){ res.redirect(\'/product\'); } }) //res.send(\'productdelete\'); })
路由模块化
基本功能完成的差不多,我们来改造下刚写的代码
首先,改造一下 app.js
页面,修改如下:
var express=require(\'express\'); //引入模块 var admin =require(\'./routes/admin.js\'); var index =require(\'./routes/index.js\') var app=new express(); /*实例化*/ //admin //admin/user app.use(\'/\',index); app.use(\'/admin\',admin); app.listen(3000,\'127.0.0.1\');
……
完整代码请查看GitHub源码,如有问题请直接在 Issues 中提,或者您发现问题并有非常好的解决方案,欢迎 PR
以上是关于Node.js Express+Mongodb 项目实战的主要内容,如果未能解决你的问题,请参考以下文章
错误状态:使用 Node.js (express)、Angular 和 MongoDB 的 PUT 请求返回 404
Node.js+Express+MongoDB数据库实现网页注册登入功能
Node.js 文件上传(Express 4、MongoDB、GridFS、GridFS-Stream)