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

Posted 余朝忠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用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

 

  

  

以上是关于使用express4.x版Jade模板以及mysql重写《nodejs开发指南》微博实例的主要内容,如果未能解决你的问题,请参考以下文章

《nodejs开发指南》微博实例常见错误汇总express4.x.x+jade

express 4.0x 用ejs妫傻腶pp.js没有app.configure,怎么弄

Node+express4.x安装以及webstrom的使用

nodejs创建ejs工程

Jade(Pug) 模板引擎使用文档

jade——创建第一个jade模板