大家知道js现在不仅仅可以写前端界面而且可以写后端的业务了,这样js就可以写一个全栈的项目。这里介绍一个nodejs + express + mongodb + bootstap 的全栈项目。

  1、安装必要的包,npm install express  npm install mongodb npm install ejs (需要使用什么工具,就安装哪个工具)

  2、建一个入口文件,index.js,这里主要是做路由的分发。启动:   node index.js

var express = require("express");// require express 的框架
var app = express(); // 实例化一个 express的对象
var router = require("./router/router.js"); // 引用 router 的文件,下面将介绍这个router
var session = require('express-session');// 使用了 express 一个 session 的工具,主要用作注册登录使用
var config = require("./config.js");// 引用一个配置文件//使用session
app.use(session({secret: 'keyboard cat',resave: false,saveUninitialized: true,
}));
//设置跨域访问  在做前后端分离,nodejs提供接口的时候,这个设置跨域请求必不可少
  app.all('*', function(req, res, next) {
     res.header("Access-Control-Allow-Origin", "*"); // 表示任意的源
    // res.header("Access-Control-Allow-Origin", "http://www.wtapi.wang"); // 只有这个网址
    res.header("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",'unknown')
    res.header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    next();
});
app.set("view engine","ejs");
app.set('views', path.join(__dirname, 'views'));

app.use(express.static("./assets"));// 静态一个文件夹,实用的好处这里的文件的路径就可以 用  /   表示
app.get("/",router.index); // 后端分发的路由 "/" 表示主页 主页的业务代码逻辑在 router里的 index 的函数里//我的发布
// app.get("/mypost", routerUser.list);
//search
// app.get("/search",routerSearch.list);//执行登陆业务
app.post("/doLogin",router.doLogin);
app.post("/doCinemaSubmit",router.doCinemaSubmit);
//个人中心页// app.get("/usercenter",router.showUserCenter);

app.get("/cinema/:targetId",router.showSelectPage);app.post('/seatHandle', router.seatHandle)
//退出
app.get("/user_exit",router.logout);//提交修改密码
app.post("/reviseMyMsg",router.reviseMyMsg);app.listen(config.port, function () {console.log("项目启动成功: " + config.port);
});

3、处理后端业务数据逻辑的router,这里router 名字可以随便取,贴切的话可以 命名为 controller  或者 model  ,两个命名规范的业务划分,我统统集合在这个一个文件里。

//又提交,引入formidable
var formidable = require("formidable"); // 一个前台提交到后端接受数据的一个包,缺点: 没办法接受前端传来的数组数据
//引入封装好的db.js,从config走
var db = require("../model/db.js"); // 这里的解释转到4 

var path = require("path");
var fs = require("fs");var mongo = require('mongodb');
var Ob = mongo.ObjectID;
var userData = {};// post 请求的一种方式
//注册业务 这是一个post 的请求,接受前端传来的数据做业务处理,处理后返回前端     res.send('....')  前端ajax 获得一个返回状态,做前端数据处理
exports.doRegist = function (req,res,next) {var form = new formidable.IncomingForm();form.parse(req, function(err, fields, files) {var username = fields.username;var userpassword = fields.userpassword;var sharecode = fields.sharecode;// 邀请码if (!sharecode){res.send("-11");return;}if (!Ob.isValid(sharecode)){res.send("-11");return;}// sharecode = "59ac32bbab6a439ed60ebb74"; 测试用db.find(ds.SHARECODE, {"_id":mongo.ObjectID(sharecode)}, function(err, result){if (err){res.send("-11");return;}if (result.length == 0){res.send("-11");return;}db.find("users",{"username": username},function (err,result) {if(err) {res.send("-3");return;}if(result.length !=0) {//数据库查询到有数据占用res.send("-1");//被占用return;}//设置MD5加密userpassword = md5(md5(userpassword)+"adou");//返回result.length的长度为0,说明数据库中没有此名字db.insertOne("users",{"msgnum" : 0,"username" :  username,"userpassword" :  userpassword,"nickname" :  '',"avatar" : "/user/default.jpg"},function(err,result){if(err){res.send("-3");//服务器错误return;}refresh(req,res,username);// 删除此邀请码db.deleteMany(ds.SHARECODE, {"_id":mongo.ObjectID(sharecode)}, function(err, result){});});});  });});
}
// //执行登录
exports.doLogin = function (req,res,next) {var form = new formidable.IncomingForm();form.parse(req, function(err, fields, files) {//表单数据var username = fields.username;var userpassword = fields.userpassword;userpassword_handel= md5(md5(userpassword)+"adou");db.find("users",{"username" : username},function(err,result){if(err){res.send("-5");//随便去,服务器错误return;}if(result.length == 0){res.send("-1");//用户名不存在return;}if(userpassword_handel == result[0].userpassword){req.session.login = "1";req.session.username= username;req.session.uid = result[0]._id;console.log(req.session.uid, "login", Math.floor(new Date().getTime()/1000));res.send("1");return;}else{res.send("-2");//密码错误return;}});})
}

// get 请求的一个方式
//访问首页 
exports.index = function (req,res,next) {
console.log("router: [/]:exports.index");
var login = req.session.login;
var username = req.session.username;
var userinfo = util.getLoginUser(req);
// 渲染一个页面,将相关的数据渲染到页面上 res.render('url',{data})
res.render('index',{ // index 是一个页面转到 5 
userinfo:{'login':login,'username':username}
})
}

 

4、上面引入的 db.js 是有关操作数据库的操作,对原始的mongdb 的语法,做了一下封装。

//这个模块里面封装了所有对数据库的常用操作
var MongoClient = require('mongodb').MongoClient;
var config = require("../config.js");
//不管数据库什么操作,都是先连接数据库,所以我们可以把连接数据库
//封装成为内部函数
function _connectDB(callback) {var url = config.dburl;   //从 config.js 文件中,都数据库地址//连接数据库MongoClient.connect(url, function (err, db) {if (err) {callback(err, null);return;}callback(err, db);});
}//插入数据
exports.insertOne = function (collectionName, json, callback) {_connectDB(function (err, db) {db.collection(collectionName).insertOne(json, function (err, result) {callback(err, result);db.close(); //关闭数据库
        })});
};
// insertmany
exports.insertMany = function(cname, arr){_connectDB(function (err, db) {db.collection(cname).insertMany(arr, function (err, result) {db.close();});});
}
exports.removeAll = function(cname, cb){_connectDB(function (err, db) {db.collection(cname).deleteMany({}, function (err, result){cb(err, result);db.close();});});
}
//查找数据,找到所有数据。args是个对象{"pageamount":10,"page":10}
exports.find = function (collectionName, json, C, D) {var result = [];    //结果数组if (arguments.length == 3) {//那么参数C就是callback,参数D没有传。var callback = C;var skipnumber = 0;//数目限制var limit = 0;} else if (arguments.length == 4) {var callback = D;var args = C;//应该省略的条数var skipnumber = args.pageamount * args.page || 0;//数目限制var limit = args.pageamount || 0;//排序方式var sort = args.sort || {};} else {throw new Error("find函数的参数个数,必须是3个,或者4个。");return;}//连接数据库,连接之后查找所有_connectDB(function (err, db) {var cursor = db.collection(collectionName).find(json).skip(skipnumber).limit(limit).sort(sort);cursor.each(function (err, doc) {if (err) {callback(err, null);db.close(); //关闭数据库return;}if (doc != null) {result.push(doc);   //放入结果数组} else {//遍历结束,没有更多的文档了callback(null, result);db.close(); //关闭数据库
            }});});
}//删除
exports.deleteMany = function (collectionName, json, callback) {_connectDB(function (err, db) {//删除
        db.collection(collectionName).deleteMany(json,function (err, results) {callback(err, results);db.close(); //关闭数据库
            });});
}
// findmany
exports.findmany = function(cname, con, filter, cb){_connectDB(function (err, db) {db.collection(cname).find(con, filter).toArray(function(err, docs){cb(err, docs);db.close();});});
};
// findone
exports.findone = function(cname, con, op, cb){_connectDB(function (err, db) {db.collection(cname).findOne(con,{fields:op}, function(err, doc){cb(err, doc);db.close();});});
};
//修改
exports.updateMany = function (collectionName, json1, json2, callback) {_connectDB(function (err, db) {db.collection(collectionName).updateMany(json1,json2,function (err, results) {callback(err, results);db.close();});})
};exports.getAllCount = function (collectionName,callback) {_connectDB(function (err, db) {db.collection(collectionName).count({}).then(function(count) {callback(count);db.close();});})
}exports.count = function(cname,cond,cb){_connectDB(function (err, db) {db.collection(cname).count(cond).then(function(count) {cb(count);db.close();});});
}exports.one = function(cname, cond, cb){_connectDB(function (err, db) {db.collection(cname).count(cond).then(function(err, one) {cb(err, one);db.close();});});
}

5、具体到前端页面

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>管理系统</title><% include component/css.ejs %>  // ejs 的一个模版,把相同的东西,封装在一个 模板里,然后各个页面  include 这个模板</head><body class="index-body"><div><%= userinfo.login%></div>  // ejs 模板渲染  渲染的数据 直接用  <%= data%> 表示

  <div><%= userinfo.username%></div> // 
</body> </html>

这样的话,一个前端到后端,后端处理前端传来的数据,nodejs 操作数据库,并返回数据给前端的流程就走通了。

这里不是前后端分离,这里采用的是后端渲染的方式,也就是,后台将页面渲染好,然后返回到前端。

nodejs 做后台的一个完整业务整理相关推荐

  1. 实战总结:我是怎么从0到1做后台业务系统的?

    本文由作者 无人知晓 发布于社区 前言 从0到1设计一套系统,是一个产品经理成长的必经之路.在过去几年中,我积累了很多企业内部业务系统从0-1的经验,本文重点将其进行抽象总结,并总结那些掉进去的坑和是 ...

  2. 从前端到后台,开发一个完整功能的小程序

    原址 <微信小程序开发入门>专栏前面的文章主要介绍了小程序前端的开发,对于一个较复杂和完整功能的小程序都是需要后台的支撑的,比如数据的获取和存储.逻辑的处理等.  后台的开发,可以选择PH ...

  3. 一个完整的区块链入门整理,良心推荐

    一个完整的区块链入门整理,良心推荐!!! 入门介绍与原理: 一.比特币 1.比特币白皮书 –来自百度网盘超级会员V8的分享 这是一切的开始 2.精通比特币 提取码:mj86 讲比特币很详细的一本书,看 ...

  4. 只需八步,做一个完整的数据分析

    公众号后台回复"图书",了解更多号主新书内容作者:小熊妹来源:码工小熊 很多小伙伴不清楚做数据分析的流程,经常疑惑:到底做到什么程度才算是一个完整的分析?其实,数据分析是有标准模板 ...

  5. 老总让做后台接口监控,我却开发了一个App

    最近投入到了一个新的项目中,是一个新的Android项目,项目涉及到智能聊天相关的功能,所以需要一个很好的接入层,总之肯定不能用通用的http协议来聊天. 手Q.微信等聊天软件,都会实现自己的一套协议 ...

  6. 用PaddleDetection做一个完整的目标检测项目(上)

    文章转载自:微信公众号:飞桨PaddlePaddle的微信文章 原文章中由于排版问题,导致文字遮挡,不便阅读,因此对文章格式稍作更改,增加了一些关键词加粗,便于后续阅读. PaddleDetectio ...

  7. 一个完整的测试流程包括哪些?测试人员需要做什么?

    目录 前言 1.需求交接 2.编写测试用例 3.冒烟测试 4.SIT测试 5.数据升级测试(视情况而定) 6.系统培训(视情况而定) 7.UAT测试 8.上线 结语 前言 在实际工作中,其实很少有公司 ...

  8. pycharm里怎么关闭一个项目_【周末分享】一个完整的项目复盘到底要怎么做?...

    点击"阅读原文",注册会员,海量活动方案免费拿 作者 | 杨阳(广告创意主笔) 来源 | 广告创意(ID:idea1408) 字数:3099 推荐阅读时长:5min 从计划到执行到 ...

  9. 如何使用graphpad做柱形图_系列文章 如何使用PaddleDetection做一个完整项目(三)...

    系列文章 如何使用PaddleDetection做一个完整项目(三) 该文章是PaddleDetection的完结篇,请参考之前两篇文章 https://zhuanlan.zhihu.com/p/10 ...

  10. 使用layui 做后台管理界面,在Tab中的链接点击后添加一个新TAB的解决方法

    使用layui 做后台管理界面,在Tab中的链接点击后添加一个新TAB的解决方法 参考文章: (1)使用layui 做后台管理界面,在Tab中的链接点击后添加一个新TAB的解决方法 (2)https: ...

最新文章

  1. 精美jQuery插件及源码 前端开发福利
  2. boost解析info文件
  3. 虚拟DOM Diff算法解析
  4. 系统启动 之 Linux系统启动概述(2)
  5. 外包以小时计算金额的费用_基金申购赎回费用计算实例
  6. POJ-3421 X-factor Chains---求因子+递推 或 素因子+组合数学
  7. java版本不兼容_java 中jdk版本不兼容的问题小记
  8. OpenResty(nginx)操作redis的初步应用
  9. Python之 continue继续循环
  10. python select實現非阻塞socket
  11. 如何运行PowerShell的脚本文件
  12. sshd启动报错解决:Missing privilege separation directory: /run/sshd
  13. LeetCode每日一题——两数相加
  14. 【大数据部落】文本挖掘:twitter推特LDA主题情感分析
  15. Python 读取/存储 yaml 文件
  16. 共226款Html5小游戏源码分享
  17. UITableView分段加载数据
  18. 微信小程序开发者文档 开放文档 地址
  19. python100份教材/教程分享学习,初中高级总有适合你的
  20. pandownload复活版下载 | 百度网盘下载速度慢的终极解决方案

热门文章

  1. linux挂载曙光存储,曙光I1620G30获取设备的cpu、内存、存储等参数信息。
  2. mysql建三行三列表格_基于另一个表中列的名称在mysql中创建表
  3. 258. Move 0s To The End I -- Laicode
  4. php循环5000条会不会崩,PHP -- 循环
  5. 动手设计 CPU(三)—— 微程序控制的存储器读写系统设计
  6. 仿射组合(Affine Combination)的定义与性质
  7. Charlotte:不会被检测到的Shellcode启动器
  8. 痕迹清理 - Windows
  9. 1.两数之和(力扣leetcode) 博主可答疑该问题
  10. Redis学习与实战之列表