使用express4.x版、Jade模板以及mysql重写《nodejs开发指南》微博实例

  最近阅读《nodejs开发指南》一书,书是不错的,然而其微博代码示例用的是express3.x,用些过时了,运行代码出现不少bug(我电脑安的是express4.x),于是用express4.x+jade模板重写一遍(原代码使用的是ejs模板)。因为想体验一下node结合MySQL开发,于是将mongodb改为mysql。下面进入正文

  1、安装express框架与生成器:

  

  

  2、进入网站目录,创建项目:

  

  3、安装中间件与依赖项:

  

  package.json如下

  

  单独安装时记得加上--save,便于项目迁移重新安装中间件。

  4、启动项目:

  先安装supervisor,启动实时监控文件修改并重新启动服务器,这样就不用每次修改文件都重新启动服务器。

  

  启动项目

  

  5、看看我的项目目录

  

  configs放配置文件,写法遵循commonjs规范。

  install放安装所需文件,安装时读取sql代码连接数据库创建数据表并插入数据,有后台管理时创建保存管理员账号,完成安装时声称lock.txt文件。方便项目迁移。

   log放日志文件,access是访问日志,error是错误日志

  public放静态资源文件。

  models为模型操作文件,相当于为MVC中的M;routes为路由文件,相当于为MVC中的C以及路由解析分发;view为V,视图层。

  utils防止工具类文件以及第三方工具类文件

  cluster.js为充分调用电脑多核资源所写,根据核数量创建相应数量进程运行app.js。运行 supervisor cluster.js

  6、下面看源代码:

  cluster.js

var cluster  = require(‘cluster‘);
var os = require(‘os‘);
var cpuNum = os.cpus().length;

var workers = {};

if(cluster.isMaster){  //主进程
    //当一个进程结束,重启工作进程
    cluster.on(‘death‘,function(worker){
        delete workers[worker.pid];
        worker = cluster.fork();
        workers[worker.pid] = worker;
    })

    //根据CPU数量创建相应数量的进程
    for(var i=0; i<cpuNum;i++){
        var worker = cluster.fork();
        workers[worker.pid] = worker;
    }

}else{//工作进程
    var app = require(‘./app‘);
    app.listen(3000);

}

//当主进程终止,关闭所有主进程
process.on(‘SIGTERM‘,function(){
    for(var pid in workers){
        precess.kill(pid);
    }
    process.exit(0);
})

  app.js

var express = require(‘express‘);
var logger = require(‘morgan‘);
var fs = require(‘fs‘);
var fileStreamRotator = require(‘file-stream-rotator‘)
var cookieParser = require(‘cookie-parser‘);
var session = require(‘express-session‘);
var bodyParser = require(‘body-parser‘);
var path = require(‘path‘);
var favicon = require(‘serve-favicon‘);
var flash  = require(‘connect-flash‘);

var index = require(‘./routes/index‘);
var user = require(‘./routes/user‘);

var app = express();

// 设置模板引擎与模板目录
app.set(‘views‘, path.join(__dirname, ‘views‘));
app.set(‘view engine‘, ‘jade‘);

// 日志输出到文件系统,每日一个日志文件
var accessLogDirectory = __dirname + ‘/logs/access‘;
fs.existsSync(accessLogDirectory) || fs.mkdirSync(accessLogDirectory);
var errorLogDirectory = __dirname + ‘/logs/error‘;
fs.existsSync(errorLogDirectory) || fs.mkdirSync(errorLogDirectory);

var accessLogStream = fileStreamRotator.getStream({
    filename:accessLogDirectory+‘/access-%DATE%.log‘,
    frequency:‘daily‘,
    verbose:false
})
app.use(logger(‘combined‘,{stream:accessLogStream}));
// 设置错误日志文件地址
var errorLogStream = fs.createWriteStream(errorLogDirectory+‘/error.log‘,{‘flags‘:‘a‘});

//将请求体放入request.body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//处理cookie
app.use(cookieParser());
//处理session
app.use(session({
    secret:‘testexpress‘,
    cookie: { maxAge: 60000 },
    resave: true,
    saveUninitialized: true
}))

// 设置icon图标
app.use(favicon(path.join(__dirname, ‘public‘, ‘favicon.ico‘)));
//flash支持
app.use(flash());
//静态文件借口
app.use(express.static(path.join(__dirname, ‘public‘)));

// 挂靠路由中间件
app.use(‘/‘, index);
app.use(‘/index‘, index);
app.use(‘/user‘, user);

//404错误处理句柄
app.use(function(req, res, next) {
  var err = new Error(‘Not Found‘);
  err.status = 404;
  next(err);
});

//错误处理
app.use(function(err, req, res, next) {

  var error = (req.app.get(‘env‘) === ‘development‘ )? err : {};

  //写错误日志
  var errorMes = ‘[‘+Date()+‘]‘+req.url+‘\n‘+‘[‘+error.stack+‘]‘+‘\n‘;
  errorLogStream.write(errorMes);

  // 写回错误处理代码
  res.status(err.status || 500);
  res.render(‘error‘,{‘message‘:err.message,‘error‘:error});
});

//防止服务器自启动。只许在外部模块调用
if(!module.parent){
    app.listen(3000,function(){
        console.log("Server listening on port %d in %s",3000,app.settings.env);
    });
}

module.exports = app;

  routes/index.js

var express = require(‘express‘);
var router = express.Router();

var News = require(‘../models/news‘);

/* GET home page. */
router.get(‘/‘, function(req, res, next) {
    News.get(null,function(err,news){
        var user = null;
        if(err){
            news = [];
        }
        if(req.session.user){
            user = req.session.user;
        }
        res.render(‘index/index‘, {
              title: ‘微博首页‘,
              news:news,
              user:user
          });
    })
});

module.exports = router;

  routes/user.js

var express = require(‘express‘);
var router = express.Router();

var User = require(‘../models/user‘);
var News = require(‘../models/news‘);

var crypto = require(‘crypto‘);

//访问用户页面
router.get(‘/:user‘, function (req, res) {
  User.get(req.params.user,  function (err, user) {
    if (!user) {
     console.log(req.session);
      req.flash(‘error‘, ‘ 用户不存在‘);
       return  res.redirect(‘/‘);
    }
    console.log(user);
    News.get(user.username, function (err, news) {
       if (err) {
        req.flash(‘error‘, err);
         return  res.redirect(‘/‘);
      }
      res.render(‘user/index‘, {
        username: user.username,
        news: news
      });
    });
  });
});

//访问注册页
router.get("/reg",checkNotLogin);
router.get("/reg",function(req,res){
    res.render(‘reg‘,{
        ‘title‘:‘用户注册‘
    })
})
//提交注册信息
router.post(‘/reg‘,checkNotLogin);
router.post(‘/reg‘,function(){
    if(req.body[‘password-repeat‘]!=req.body[‘password‘]){
            req.flash(‘error‘,‘两次输入的口令不一致‘);
            return res.redirect(‘/reg‘);
        }
    var md5 = crypto.createHash("md5");
    var password = md5.update(req.body.password).digest(‘base64‘);
    var  newUser =  new  User({
        name: req.body.username,
        password: password
    })

  //检查用户名是否已经存在
    User.get(newUser.name, function (err, user) {
        if (user)
          err = ‘Username already exists.‘;
        if (err) {
          req.flash(‘error‘, err);
          return res.redirect(‘/reg‘);
        }
        // 如果不存在则新增用户
        newUser.save(function (err) {
            if (err) {
                req.flash(‘error‘, err);
                 return  res.redirect(‘/reg‘);
             }
            req.flash(‘success‘, ‘ 注册成功‘);
            res.redirect(‘/login‘);
        });
    });
})

//用户访问登录页
router.get(‘/login‘, checkNotLogin);
router.get(‘/login‘,  function (req, res) {
  res.render(‘login‘, {
    title: ‘用户登入‘
  });
});
//用户提交账号信息
router.post(‘/login‘,checkNotLogin);
router.post(‘/login‘, function (req, res) {
     //生成口令的散列值
    var  md5 = crypto.createHash(‘md5‘);
    var  password = md5.update(req.body.password).digest(‘base64‘); 

    User.get(req.body.username, function (err, user) {
        if (!user) {
          req.flash(‘error‘, ‘ 用户不存在‘);
           return  res.redirect(‘/login‘);
        }
        if (user.password != password) {
          req.flash(‘error‘, ‘ 用户密码错误‘);
           return  res.redirect(‘/login‘);
        }
        req.session.user = user;
        req.flash(‘success‘, ‘ 登入成功‘);
        res.redirect(‘/‘);
    });
})

//用户退出
router.get(‘/logout‘,checkLogin);
router.get(‘/logout‘, function (req, res) {
    req.session.user =  null;
    req.flash(‘success‘, ‘登出成功‘);
    res.redirect(‘/‘);
});

//找回密码
router.get(‘/getPwd‘,checkNotLogin);
router.get(‘/getPwd‘,function(req,res){
    res.render(‘getpwd‘, {
    title: ‘密码找回‘,
  });
})

router.post(‘/getPwd‘,checkNotLogin);
router.post(‘/getPwd‘,function(req,res){
    User.get(req.body.username, function (err, user) {
        if (!user) {
          req.flash(‘error‘, ‘ 用户不存在‘);
           return  res.redirect(‘/getPwd‘);
        }
        req.flash(‘success‘, ‘成功找回密码:‘+user.password);
        res.redirect(‘/login‘);
    });
})

//发表微博
router.post(‘/news‘, checkLogin);
router.post(‘/news‘,  function (req, res) {
  var  currentUser = req.session.user;
  var  post =  new  Post(currentUser.name, req.body.post);
  post.save(function (err) {
    if (err) {
      req.flash(‘error‘, err);
       return  res.redirect(‘/‘);
    }
    req.flash(‘success‘, ‘ 发表成功‘);
    res.redirect(‘/u/‘ + currentUser.name);
  });
});

function  checkLogin(req, res, next) {
  if (!req.session.user) {
    req.flash(‘error‘, ‘未登入‘);
    return  res.redirect(‘/login‘);
  }
  next();
}

function checkNotLogin(req, res, next) {
  if (req.session.user) {
    req.flash(‘error‘, ‘已登入‘);
    return res.redirect(‘/‘);
  }
  next();
}

module.exports = router;

configs/settings.js

(function(){
   var settings;
   settings = {
          mysql:{
                  host:‘localhost‘,
                  prot:‘3306‘,
                  user:‘root‘,
             password:‘‘,
             database:‘node_microblog‘
          },
      mongodb:{
           host:‘localhost‘,
           prot:‘27017‘,
           user:‘root‘,
          password:‘‘,
          database:‘node_microblog‘
      }

   }
   module.exports = settings;
})()

utils/database.js

 (function(){

         var settings = require(‘../configs/settings‘);
         var mysql = require(‘mysql‘);
         var client = null;

         var default_sql = require

         exports.getDbCon = function(){
             try{
                 if(client){
                     client = mysql.createConnection(settings.mysql);
                     client.connect();
                 }else{
                     client = new mysql.createConnection(settings.mysql);
                     client.connect();
                 }
             }catch(_error){
                 throw _error;
             }
             return client;
         }

         exports.install = function(){

         }
 })()
 

models/news.js

var database = require(‘../utils/database‘);
mysql = database.getDbCon();

function News(username,content,time){
    this.username = username;
    this.content = content;
    if (time) {
        this.time = time;
    } else {
        this.time =  new Date ();
        console.log(this.time);
    }
}

//保存消息
News.prototype.save = function(callback){

    var sql = "select id from user where username = ‘"+this.username+"‘";
    mysql.query(sql,function(err,results,fields){
        if(err){
            throw err;
        }
        if(results){
            this.uid = results[0].id;
        }
        var  news = {
            username: this.uid,
            content: this.conetnt,
            time: this.time
         };

        sql = "insert into user(uid,content,time) values(?,?,?)";
        mysql.query(sql,[news.uid,news.content,news.time],function(err,results,fields){
            if (err) {
                throw err;
            } else {
                //返回用户id
                return callback(err,fields);
            }
        })
    })
};

//获取消息
News.get = function(username,callback){

    var sql ="select * from news";
    if( username){
        sql +=" join user on user.id=news.uid where username=‘"+username+"‘";
    }
    mysql.query(sql,function(err,results,fields){
        if(err){
            throw err;
        }else{
            callback(err,results,fields);
        }
    })
}

module.exports = News;

models/user.js

var database = require(‘../utils/database‘);
mysql = database.getDbCon();

function User(user){
    this.username = user.username;
    this.password = user.password;
}

//保存用户
User.prototype.save = function(callback){
    var  user = {
        username: this.username,
        password: this.password
    };

    var sql ="insert into user (username,password) values(?,?)";

    mysql.query(sql,[user.username,user.password],function(err,results,fields){
        if (err) {
            throw err;
        } else {
            //返回用户id
            return callback(err,fields);
        }
    });
};

//获取用户
User.get = function(id,callback){
    var sql = "select * from user where id=‘"+id+"‘";
        mysql.query(sql,function(err,results,fields){
            if(err){
                throw err;
            }else{
                callback(err,results[0],fields);
            }
        })
}

module.exports = User;

  源代码下载:https://github.com/yujon/node_microblog

  

  

时间: 2024-10-11 17:42:26

使用express4.x版、Jade模板以及mysql重写《nodejs开发指南》微博实例的相关文章

《nodeJs开发指南》博客demo重写(jade+MySQL)

整体感觉jade没有ejs好用呢... jade的格式完全是根据tab和space来判断的,感觉就不是特别方便,在程序方面可能还有很多不成熟的地方,希望大家能指出来! 特别感谢一下几位大神的分享: 1.http://www.cnblogs.com/haogj/p/3985438.html 迁移到 Express 4.x 2.https://cnodejs.org/topic/53f23e198f44dfa35129c43b 使用express4.x版和Jade模板重写<nodejs开发指南>微

zabbix用自带的模板监控mysql

先看一下zabbix自带的mysql模板监控项: #很少是吧,没事生产环境一般我们不用,下一篇将介绍生产环境用的另一种mysql监控. 配置zabbix自带的模板监控mysql数据库:

jade模板

jade 模板使用 npm install jade -g      安装到全局 jade index.jade         导出一个 index.html 压缩后的 jade -P index.jade       导出一个 index.html 没有压缩的 jade -P -w index.jade     -w  对文件实时编译 特殊的div .container p 巧巧 a(href='http://baidu.com', title='巧莉', data-uid='100') i

Zabbix-3.0.3使用自带模板监控MySQL

导读 Zabbix是一款优秀的,开源的,企业级监控软件,可以通过二次开发来监控你想要监控的很多服务,本文介绍使用Zabbix自带的模板监控MySQL服务. 配置userparameter_mysql.conf #移动到zabbix解压缩路径 cd /usr/local/src/zabbix-3.0.3/conf/zabbix_agentd #拷贝文件到/opt/zabbix/etc/zabbix_agentd.conf.d/ #指定自己的zabbix安装目录 cp userparameter_m

jade模板引擎

jade是使用JavaScript实现,可供nodejs使用的高性能模板引擎(性能高不高,有些争议.姑且称之为高性能吧!).模板引擎有很多,主要使用比较广泛的是jade和ejs,modejs项目默认使用jade作为模板引擎,我也就不多说了至于如何选择,还是得就事论事综合各种因素来考虑.在此不对优缺点进行分析.插一句嘴,ejs的语法更像jsp.asp这样的技术而jade更像python的语法风格,缩进来缩进去,有点绕.不过这并不影响代码的可读性(我是这么认为的).不管是jade还是ejs语法都比较

zabbix利用自带的模板监控mysql数据库

zabbix利用自带的模板监控mysql数据库 作者:尹正杰 有些东西你不会的时候觉得它特别难,但是当你去做的时候就发现如此的简单~zabbix功能的强大我在这里就不多说了,好不好 使你用用就知道了,哈哈······, 其实zabbix监控agent端的mysql数据库原理上很简单,就是你需要在zabbix客户端新建一个用户,这个用户的账号密码存放到 隐藏的文件中,(也是考虑安全性嘛~),服务端通过读取这个配置文件的用户密码去登陆数据库,然后把采集的结果反馈给客户端, 切记我们这里不要给root

jade模板引擎简明用法

①.特性 首个单词为标签,有一些不能识别的标签可作为code,如each for case if  else if unless zen coding风格添加标签,如 .nb#hello 生成 <div class="nb" id="hello"></div> 缩进必须统一使用tab或space,否则会报错 通过缩进来表示嵌套关系,这个很重要!如 p a   生成 <p><a></a></p>

Node.js开发入门—使用jade模板引擎

在"Node.js开发入门--Express安装与使用"里,我们曾经使用express generator创建了一个HelloExpress网站,express工具为我们生成了基本的目录结构.模板.stylesheet.routers等.虽然那只是一个简单的HelloWorld类的小东西,可里面包含的内容还是有些多了,为了更好的理解Express所支持的jade模板引擎的用法,我们这次提供一个手动创建的小网站,可以显示来访者的IP,并对访问进行计数. 安装jade npm instal

Node.js开发 ---- Jade 模板引擎使用

1.安装jade插件npm install jade 2.app.js[javascript] view plain copy 在CODE上查看代码片派生到我的代码片var express = require('express'); var http = require('http'); var app = express(); app.set('view engine', 'jade'); // 设置模板引擎 app.set('views', __dirname); // 设置模板相对路径(相