新尝试另一个语言node.js和框架express,记录一些基本的操作与技巧。
此次最大的不同是node.js是异步的,有些操作就不那么直观。
这里在linux centos做测试。前提先安装好node.js和npm。
这里也类似上次flask完成一个登陆与增删改操作的接口。
先用命令行直接生成一个项目
npm install express-generator -g express --view=pug myapp
cd myapp && npm install npm start
app.js主文件
//最后两个为session所需库,还有mongodb库,需自行下载 //npm install --save express-session,session-file-store,mongodb var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var session = require('express-session'); var FileStore = require('session-file-store')(session); #引入路由文件 var RetInfo = require("./common/retinfo"); var index = require('./routes/index'); var users = require('./routes/users'); var manage = require('./routes/manage'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'pug'); //解析请求body // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); //开启并设置session app.use(session({ secret: 'chyingp', store: new FileStore(), saveUninitialized: false, resave: false, cookie: { maxAge: 24*60*60*1000 } })); //绑定路由,中间件 app.use('/', index); app.use('/users', users); //不设置的则下面的路由都会运行这个函数 app.use(function(req,res,next) { var sess = req.session; var loginUser = sess.loginUser; if(loginUser===undefined) return res.json(RetInfo.error("login out")); next(); }); //绑定另一个中间件,需登录后 app.use('/manage',manage); //错误处理 // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
根目录下 新建一个文件夹common/用于存放通用函数,下面写了两种形式。
common/retinfo.js 用于接口返回数据
module.exports = { response : function(sts,msg) { return {"sts":sts,"msg":msg} }, success : function() { return this.response(1,"success") }, error : function(msg) { return this.response(-1,msg) }, dberr : function(msg) { return this.response(-1,"db error"); } }
common/mongodb.js 用于数据库操作,这里使用了promise,因为mongodb操作后会有回调函数,不方便调用,写成promise就可以用then进行下去。
//use for mongodb database var MongoClient = require('mongodb').MongoClient; function Mongodb(dbName, colName){ this.dbName = dbName; this.colName = colName; this.url = 'mongodb://localhost:27017/'; this.fetch = function(params){ //回调函数里没法获取到外部的this,所以再定义一下that var that = this; return new Promise(function(resolve, reject, notufy) { MongoClient.connect(that.url, function(err, db){ if(err) reject(err); var dbo = db.db(that.dbName); dbo.collection(that.colName).find(params).toArray(function(err, res){ if(err) reject(err); resolve(res); db.close(); }); }); }); }; this.save = function(params){ var that = this; return new Promise(function(resolve, reject, notufy){ MongoClient.connect(that.url, function(err, db){ if(err) reject(err); var dbo = db.db(that.dbName); dbo.collection(that.colName).insertOne(params, function(err, res){ if(err) reject(err); resolve(res); db.close(); }); }); }); }; this.delete = function(params){ var that = this; return new Promise(function(resolve, reject, notufy){ MongoClient.connect(that.url, function(err, db){ if(err) reject(err); var dbo = db.db(that.dbName); dbo.collection(that.colName).deleteOne(params, function(err, res){ if(err) reject(err); resolve(res); db.close(); }); }); }); } this.update = function(whparams,params){ var that = this; return new Promise(function(resolve, reject, notufy){ MongoClient.connect(that.url, function(err, db){ if(err) reject(err); var dbo = db.db(that.dbName); dbo.collection(that.colName).updateOne(whparams, {$set:params}, function(err, res){ if(err) reject(err); resolve(res); db.close(); }); }); }); } } module.exports = Mongodb;
然后编写中间件routes/users.js
var express = require('express'); var router = express.Router(); var RetInfo = require("../common/retinfo"); //登录 router.get('/login', function(req, res, next) { username = req.query.username; password = req.query.password; if(!username || !password) return res.json(RetInfo.error("lack of params")); if(username == "admin" && password == "admin"){ req.session.regenerate(function(err) { if(err) return res.json(RetInfo.error("login error")); req.session.loginUser = username; return res.json(RetInfo.success()); }); }else{ return res.json(RetInfo.error("username or password error")); } }); //登出 router.get("/loginout", function(req, res, next) { req.session.destroy(function(err) { if(err) return res.json(RetInfo.error("login out error")); return res.json(RetInfo.success()); }); }) module.exports = router;
routes/manage.js 这里写了一般的增删改操作
var express = require('express'); var router = express.Router(); var RetInfo = require("../common/retinfo"); var Mongo = require("../common/mongodb"); DB_POSTS = new Mongo("test_database","posts"); //获取数据 router.get("/",function(req, res, next){ DB_POSTS.fetch({}).then((data)=>{ return res.send(data); },(err)=>{ return res.send(RetInfo.error(err.message)); }); }) //增加 .post("/",function(req, res, next){ DB_POSTS.save(req.body).then((data)=>{ return res.send(RetInfo.success()); },(err)=>{ return res.send(RetInfo.error(err.message)); }); }) //删除 .delete("/",function(req, res, next){ data={"_id":req.query.id} DB_POSTS.delete(data).then((data)=>{ return res.send(data) },(err)=>{ return res.send(RetInfo.error(err.message)) }); }) //修改 .put("/",function(req, res, next){ const params = req.body; DB_POSTS.update({"_id":params.id},params).then((data)=>{ return res.send(RetInfo.success()); },(err)=>{ return res.send(RetInfo.error(err.message)); }) }) module.exports = router;
运行的话可以有很多方法
一般运行 npm start debug模式 DEBUG=myapp:* npm start 开发修改后自动重启 nodemon app.js 后台一直运行 forever start ./bin/www
后言:对于js语法 es6等还比较生疏,并没有涉及,可能有待改进,但总怕麻烦。。。。
版权声明:本文为原创文章,转载请注明出处和作者,不得用于商业用途,请遵守
CC BY-NC-SA 4.0协议。
赞赏一下