Nodejs學(xué)習(xí)筆記(七)--- Node.js + Express + Mysql

Node.js + Express + Mysql

1、項目:expressEjsWeb
express -e expressEjsWeb
cd expressEjsWeb&& npm install
2、數(shù)據(jù)庫:mysql
CREATE DATABASE IF NOT EXISTS learn_nodejs CHARACTER SET UTF8;

USE learn_nodejs;

SET FOREIGN_KEY_CHECKS=0;

DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo` (
  `Id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `UserName` varchar(64) NOT NULL COMMENT '用戶名',
  `UserPass` varchar(64) NOT NULL COMMENT '用戶密碼',
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶信息表';
3.修改package.json文件,安裝session和mysql模塊
"express-session" : "latest",
    "mysql" : "latest"
image.png
npm install
image.png

這幾行代碼別忘記添加署尤,之前已經(jīng)添加過肋僧。


image.png

4.樣式和JQuery文件
  樣式:樣式主要使用了bootstrap 3.0.3 https://github.com/twbs/bootstrap/releases/tag/v3.0.3
  JQuery: jquery-1.6.2.min        http://jquery.com/download/ 
  
對應(yīng)目錄結(jié)構(gòu):

image.png

路由配置

1.路由
  首頁:/
  注冊頁:/reg
  登錄頁:/login
  安全退出:/logout

2.routes目錄下新建如下文件
  reg.js
  login.js
  logout.js

3.views目錄下新建:
  header.ejs
  reg.ejs
  login.ejs

4.打開app.js文件眨唬,添加代碼

...
var routes = require('./routes/index');
var reg = require('./routes/reg');
var login = require('./routes/login');
var logout = require('./routes/logout');
...
app.use('/', routes);
app.use('/reg', reg);
app.use('/login', login);
app.use('/logout', logout);
...

實現(xiàn)登錄和注冊

image.png

user.js

var mysql = require('mysql');
var DB_NAME = 'learn_nodejs';

var pool  = mysql.createPool({
    host     : '192.168.41.36',
    user     : 'root',
    password : 'admin'
});

pool.on('connection', function(connection) {  
    connection.query('SET SESSION auto_increment_increment=1'); 
});  

function User(user){
    this.username = user.username;
    this.userpass = user.userpass;
};
module.exports = User;

pool.getConnection(function(err, connection) {

    var useDbSql = "USE " + DB_NAME;
    connection.query(useDbSql, function (err) {
         if (err) {
            console.log("USE Error: " + err.message);
            return;
         }
         console.log('USE succeed');
    });

    //保存數(shù)據(jù)
    User.prototype.save = function save(callback) {
        var user = {
            username: this.username,
            userpass: this.userpass
        };

        var insertUser_Sql = "INSERT INTO userinfo(id,username,userpass) VALUES(0,?,?)";

        connection.query(insertUser_Sql, [user.username, user.userpass], function (err,result) {

            //報錯修改地方
            connection.release();
            if (err) {
                console.log("insertUser_Sql Error: " + err.message);
                return;
            }

            //connection.release();

            console.log("invoked[save]");
            callback(err,result);                     
        });       
    };

    //根據(jù)用戶名得到用戶數(shù)量
    User.getUserNumByName = function getUserNumByName(username, callback) {

        var getUserNumByName_Sql = "SELECT COUNT(1) AS num FROM userinfo WHERE username = ?";

        connection.query(getUserNumByName_Sql, [username], function (err, result) {
             //報錯修改地方
            connection.release();
            if (err) {
                console.log("getUserNumByName Error: " + err.message);
                return;
            }

            //connection.release();

            console.log("invoked[getUserNumByName]");
            callback(err,result);                     
        });        
    };

    //根據(jù)用戶名得到用戶信息
    User.getUserByUserName = function getUserNumByName(username, callback) {

        var getUserByUserName_Sql = "SELECT * FROM userinfo WHERE username = ?";

        connection.query(getUserByUserName_Sql, [username], function (err, result) {
             //報錯修改地方
            connection.release();
            if (err) {
                console.log("getUserByUserName Error: " + err.message);
                return;
            }

            //connection.release();

            console.log("invoked[getUserByUserName]");
            callback(err,result);                     
        });        
    };
 
});

注冊

reg.ejs

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">       
    <title><%= title %></title>
  
    <link rel="stylesheet" type="text/css" href="/stylesheets/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="/stylesheets/signin.css" />
  </head>

  <body>

    <div id="container" class="container">
       <% if (locals.success) { %> 
          <div id="alt_sucess" class="alert alert-success"> 
            <%- success %> 
          </div> 
       <% } %> 

      <% if (locals.error) { %> 
        <div id="alt_warning" class="alert alert-warning"> 
          <%= error %> 
        </div> 
      <% } %> 

      <form class="form-signin" role="form" method="post">
        <h2 class="form-signin-heading">注冊</h2>

        <input id="txtUserName" name="txtUserName" type="text" class="form-control" placeholder="用戶名" required autofocus />
        <input id="txtUserPwd" name="txtUserPwd" type="password" class="form-control" placeholder="密碼" required/>
        <input id="txtUserRePwd"  name="txtUserRePwd" type="password" class="form-control" placeholder="重復(fù)密碼" required/>   

        <button id="btnSub" class="btn btn-lg btn-primary" type="submit">注  冊</button>
        <a class="btn btn-link" href="/login" role="button">登  錄</a>
      </form>  
      
    </div> 
  </body>
</html>

<script src="/javascripts/jquery-1.6.2.min.js" type="text/javascript"></script>

<script type="text/javascript">
     String.prototype.format = function (args) {
            var result = this;
            if (arguments.length > 0) {
                if (arguments.length == 1 && typeof (args) == "object") {
                    for (var key in args) {
                        if (args[key] != undefined) {
                            var reg = new RegExp("({" + key + "})", "g");
                            result = result.replace(reg, args[key]);
                        }
                    }
                }
                else {
                    for (var i = 0; i < arguments.length; i++) {
                        if (arguments[i] != undefined) {
                            var reg = new RegExp("({)" + i + "(})", "g");
                            result = result.replace(reg, arguments[i]);
                        }
                    }
                }
            }
            return result;
    }

    $(function(){
        $('#btnSub').on('click',function(){
            var 
            $txtUserName = $('#txtUserName'),
            txtUserNameVal = $.trim($txtUserName.val()),            
            $txtUserPwd = $('#txtUserPwd'),
            txtUserPwdVal = $.trim($txtUserPwd.val()),
            $txtUserRePwd = $('#txtUserRePwd'),
            txtUserRePwdVal = $.trim($txtUserRePwd.val()),
            errorTip = '<div id="errorTip" class="alert alert-warning">{0}</div> ';

            $("#errorTip,#alt_sucess,#alt_warning").remove();
            
            if(txtUserNameVal.length == 0)
            {
                $("#container").prepend(errorTip.format('用戶名不能為空'));                
                $txtUserName.focus();
                return false;
            }

            if(txtUserPwdVal.length == 0)
            {                
                $("#container").prepend(errorTip.format('密碼不能為空'));
                $txtUserPwd.focus();
                return false;
            }

            if(txtUserRePwdVal.length == 0)
            {
                $("#container").prepend(errorTip.format('重復(fù)密碼不能為空'));                
                $txtUserRePwd.focus();
                return false;
            }

            if(txtUserPwdVal != txtUserRePwdVal)
            {                 
                 $("#container").prepend(errorTip.format('兩次密碼不一致'));      
                 $txtUserPwd.focus();
                 return false;
            }

            return true;
        })
    });

</script>

實現(xiàn)注冊功能(reg.js)

var express = require('express'),
    router = express.Router(),
    User = require('../models/user.js'),
    crypto = require('crypto'),
    TITLE_REG = '注冊';

router.get('/', function(req, res) {
  res.render('reg',{title:TITLE_REG});
});

router.post('/', function(req, res) {
  var userName = req.body['txtUserName'],
      userPwd = req.body['txtUserPwd'],
      userRePwd = req.body['txtUserRePwd'],      
      md5 = crypto.createHash('md5');
 
      userPwd = md5.update(userPwd).digest('hex');

  var newUser = new User({
      username: userName,
      userpass: userPwd
  });

  //檢查用戶名是否已經(jīng)存在
  User.getUserNumByName(newUser.username, function (err, results) {        
             
      if (results != null && results[0]['num'] > 0) {
          err = '用戶名已存在';
      }

      if (err) {
          res.locals.error = err;
          res.render('reg', { title: TITLE_REG });
          return;
      }

      newUser.save(function (err,result) {
          if (err) {
              res.locals.error = err;
              res.render('reg', { title: TITLE_REG }); 
              return;            
          }        

          if(result.insertId > 0)
          {
              res.locals.success = '注冊成功,請點擊   <a class="btn btn-link" href="/login" role="button"> 登錄 </a>' ;
          }
          else
          {
              res.locals.error = err;
          }
         
          res.render('reg', { title: TITLE_REG });
          });    
    });          
});

module.exports = router;
image.png

運行:

image.png
image.png

報錯:

image.png

修改代碼:

image.png
......
  //保存數(shù)據(jù)
    User.prototype.save = function save(callback) {
        var user = {
            username: this.username,
            userpass: this.userpass
        };

        var insertUser_Sql = "INSERT INTO userinfo(id,username,userpass) VALUES(0,?,?)";

        connection.query(insertUser_Sql, [user.username, user.userpass], function (err,result) {

            
            if (err) {
                console.log("insertUser_Sql Error: " + err.message);
                return;
            }

            //connection.release();

            console.log("invoked[save]");
            callback(err,result); 
            //報錯修改地方
            connection.release();                    
        });       
    };
......

顯示:

image.png
image.png

到這里绷落,注冊功能完成!

登錄后首頁

header.ejs

<div class="navbar navbar-default navbar-static-top" role="navigation">
  <div class="container">
    <div class="navbar-header">         
      <a class="navbar-brand" href="/">Tiany - Nodejs + Express + Ejs + MySQL 示例</a>
    </div>
    <div class="navbar-collapse collapse">
      <ul class="nav navbar-nav navbar-right">

        <% if (locals.username) { %> 
          <li><a href="#">        
                <%= username %>          
          </a></li>
          <li><a href="/logout">退出</a></li> 
        <% } %>           
      </ul>
    </div>              
  </div>
</div>

index.ejs

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">           
      <title><%= title %></title>
    <link rel="stylesheet" type="text/css" href="/stylesheets/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="/stylesheets/navbar-static-top.css" />   
  </head>
  <body>
      <% include header %> 
  </body>
</html>

index.js

var express = require('express'),
    router = express.Router();

router.get('/', function(req, res) {
  if(req.cookies.islogin)
  { 
         console.log('cookies:' + req.cookies.islogin);
       req.session.username = req.cookies.islogin;
  }  

  if(req.session.username)
  {    
          console.log('session:' + req.session.username);
        res.locals.username = req.session.username;      
  }
  else
  {
        res.redirect('/login');
        return;    
  }
  res.render('index',{title:'主頁'});
});

module.exports = router;

登錄

login.ejs

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">       
    <title><%= title %></title>
  
  <link rel="stylesheet" type="text/css" href="/stylesheets/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="/stylesheets/signin.css" />
  </head>

  <body>

    <div id="container" class="container">
       <% if (locals.success) { %> 
          <div id="alt_sucess" class="alert alert-success"> 
            <%- success %> 
          </div> 
       <% } %>  

      <% if (locals.error) { %> 
        <div id="alt_warning" class="alert alert-warning"> 
          <%= error %> 
        </div> 
      <% } %> 

      <form class="form-signin" role="form" method="post">
        <h2 class="form-signin-heading">登錄</h2>
        <input id="txtUserName" name="txtUserName" type="text" class="form-control" placeholder="用戶名" required autofocus />
            <input id="txtUserPwd" name="txtUserPwd" type="password" class="form-control" placeholder="密碼" required/> 
        <label class="checkbox">
          <input name="chbRem" id="chbRem" type="checkbox" value="remember-me"> 記住密碼
        </label>              
        <button id="btnSub" class="btn btn-lg btn-primary" type="submit">登  錄</button>
        <a class="btn btn-link" href="/reg" role="button">注  冊</a>

      </form>
            
    </div> 
  </body>
</html>

<script src="/javascripts/jquery-1.6.2.min.js" type="text/javascript"></script>

<script type="text/javascript">
     String.prototype.format = function (args) {
            var result = this;
            if (arguments.length > 0) {
                if (arguments.length == 1 && typeof (args) == "object") {
                    for (var key in args) {
                        if (args[key] != undefined) {
                            var reg = new RegExp("({" + key + "})", "g");
                            result = result.replace(reg, args[key]);
                        }
                    }
                }
                else {
                    for (var i = 0; i < arguments.length; i++) {
                        if (arguments[i] != undefined) {
                            var reg = new RegExp("({)" + i + "(})", "g");
                            result = result.replace(reg, arguments[i]);
                        }
                    }
                }
            }
            return result;
    }

    $(function(){
        $('#btnSub').on('click',function(){           
            var 
            $txtUserName = $('#txtUserName'),
            txtUserNameVal = $.trim($txtUserName.val()),            
            $txtUserPwd = $('#txtUserPwd'),
            txtUserPwdVal = $.trim($txtUserPwd.val()),
            errorTip = '<div id="errorTip" class="alert alert-warning">{0}</div> ';  

            $("#errorTip,#alt_warning").remove();
            
            if(txtUserNameVal.length == 0)
            {
                $("#container").prepend(errorTip.format('用戶名不能為空'));                
                $txtUserName.focus();
                return false;
            }

            if(txtUserPwdVal.length == 0)
            {                
                $("#container").prepend(errorTip.format('密碼不能為空'));
                $txtUserPwd.focus();
                return false;
            }
            
            return true;                
        })
    });

</script>

login.js

var express = require('express'),
    router = express.Router(),
    User = require('../models/user.js'),
    crypto = require('crypto'),
    TITLE_LOGIN = '登錄';

router.get('/', function(req, res) {
    res.render('login',{title:TITLE_LOGIN});
});

router.post('/', function(req, res) {
    var userName = req.body['txtUserName'],
        userPwd = req.body['txtUserPwd'],
        isRem = req.body['chbRem'],
        md5 = crypto.createHash('md5');
       
    User.getUserByUserName(userName, function (err, results) {                            
        
        if(results == '')
        {
            res.locals.error = '用戶不存在';
             res.render('login',{title:TITLE_LOGIN});
             return;
        }

         userPwd = md5.update(userPwd).digest('hex');
         if(results[0].UserName != userName || results[0].UserPass != userPwd)
         {
             res.locals.error = '用戶名或密碼有誤';
             res.render('login',{title:TITLE_LOGIN});
             console.log(1);
             return;
         }
         else
         {
             if(isRem)
             {
                res.cookie('islogin', userName, { maxAge: 60000 });                 
             }

             res.locals.username = userName;
             req.session.username = res.locals.username;  
             console.log(req.session.username);                        
             res.redirect('/');
             return;
         }     
    });              
});

module.exports = router;

image.png
image.png

運行:

image.png

登錄成功后称杨,


image.png

對于連接經(jīng)常中斷問題
參考網(wǎng)上說明修改:
http://www.2cto.com/kf/201404/292016.html
有待實踐肌毅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市姑原,隨后出現(xiàn)的幾起案子悬而,更是在濱河造成了極大的恐慌,老刑警劉巖页衙,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摊滔,死亡現(xiàn)場離奇詭異阴绢,居然都是意外死亡,警方通過查閱死者的電腦和手機艰躺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門呻袭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腺兴,你說我怎么就攤上這事左电。” “怎么了页响?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵篓足,是天一觀的道長。 經(jīng)常有香客問我闰蚕,道長栈拖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任没陡,我火速辦了婚禮涩哟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盼玄。我一直安慰自己贴彼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布埃儿。 她就那樣靜靜地躺著器仗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪童番。 梳的紋絲不亂的頭發(fā)上精钮,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機與錄音妓盲,去河邊找鬼杂拨。 笑死,一個胖子當(dāng)著我的面吹牛悯衬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播檀夹,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼筋粗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炸渡?” 一聲冷哼從身側(cè)響起娜亿,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚌堵,沒想到半個月后买决,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沛婴,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年督赤,在試婚紗的時候發(fā)現(xiàn)自己被綠了嘁灯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡躲舌,死狀恐怖丑婿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情没卸,我是刑警寧澤羹奉,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站约计,受9級特大地震影響诀拭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜煤蚌,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一炫加、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铺然,春花似錦俗孝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至沽瘦,卻和暖如春革骨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背析恋。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工良哲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人助隧。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓筑凫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親并村。 傳聞我的和親對象是個殘疾皇子巍实,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 搭建開發(fā)環(huán)境并模擬交互數(shù)據(jù) 一、實驗說明 下述介紹為實驗樓默認(rèn)環(huán)境哩牍,如果您使用的是定制環(huán)境棚潦,請修改成您自己的環(huán)境介...
    玄月府的小妖在debug閱讀 2,122評論 0 15
  • Chapter01.簡介 NodeJS是讓JavaScript脫離瀏覽器運行在服務(wù)器的一個平臺,不是語言膝昆。 Nod...
    JunChow520閱讀 949評論 0 9
  • 22年12月更新:個人網(wǎng)站關(guān)停丸边,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,180評論 22 257
  • Koa2-blog 2018-1-5 更新教程(新增上傳頭像叠必、新增分頁、樣式改版妹窖、發(fā)布文章和評論支持markdow...
    wclimb閱讀 9,167評論 1 53
  • 詩和遠(yuǎn)方是多么的誘人嘱吗,但大部分人都是在生活的茍且中打滾玄组。 這年頭,誰都想過得自由走心谒麦,天知道人家經(jīng)歷了什么樣的磨難...
    沛沛美牙閱讀 200評論 2 2