node.js+express+mySQL+ejs+bootstrop實(shí)現(xiàn)網(wǎng)站登錄注冊(cè)功能
同志們,經(jīng)過(guò)不懈的努力,查了各種文檔,終于鼓搗出了一個(gè)稍微像樣一點(diǎn)的node項(xiàng)目,當(dāng)然如果直接拿去項(xiàng)目里用,這個(gè)demo還太簡(jiǎn)單,畢竟一個(gè)完整的登錄注冊(cè)還有很多實(shí)際的內(nèi)容,本案例mySQL的用戶列表里,為便于理解,只設(shè)置了username 和password兩個(gè)字段,正常的登錄注冊(cè),肯定會(huì)有更多的字段的。但是對(duì)于初學(xué)node的人來(lái)說(shuō),比如筆者,還是學(xué)習(xí)到了不少內(nèi)容,甚至,緊張的我不知如下下筆,肯定這個(gè)是參考了很多網(wǎng)上其他少年博客,以后這個(gè)登錄注冊(cè)demo會(huì)依據(jù)項(xiàng)目的需要而有所改進(jìn),
效果如下
效果.gif
項(xiàng)目構(gòu)架
主入口app.js
app.js為程序程序主要入口,一般主要用來(lái)寫我們引入的那些中間件及各種設(shè)置
var express = require('express'); // NodeJS中的Path對(duì)象,用于處理目錄的對(duì)象,提高開(kāi)發(fā)效率 var path = require('path'); // 用來(lái)定義網(wǎng)頁(yè)logo的中間件 var favicon = require('serve-favicon'); // NodeJs中Express框架使用morgan中間件記錄日志 // Express中的app.js文件已經(jīng)默認(rèn)引入了該中間件var logger = require('morgan'); // 使用app.use(logger('dev'));以將請(qǐng)求信息打印在控制臺(tái),便于開(kāi)發(fā)調(diào)試, // 但實(shí)際生產(chǎn)環(huán)境中,需要將日志記錄在log文件里 var logger = require('morgan'); // 存儲(chǔ)登錄信息中間件 var cookieParser = require('cookie-parser'); // 解析請(qǐng)求體的中間件 var bodyParser = require('body-parser'); // 引入模塊的js文件 var routes = require('./routes/index'); // var users = require('./routes/user'); // 引入session中間件 var session=require('express-session'); // 創(chuàng)建項(xiàng)目示例 var app = express(); // 引入我們需要的模板 app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // 用摩記錄請(qǐng)求 app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // 利用cookieParser中間件存取信息 app.use(cookieParser("Luck")); // 利用session中間件存取信息 app.use(session({ secret:'luck', resave:false, saveUninitialized:true })); // 靜態(tài)化我們的public文件下的文件,使其可以直接引用 app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); // app.use('/users', users); // 捕捉404狀態(tài) app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); module.exports = app; app.listen(3000,'127.0.0.1') routes下的index.js文件 index.js這里我用來(lái)處理頁(yè)面的路由跳轉(zhuǎn) var express = require('express'); var router = express.Router(); // 為數(shù)據(jù)庫(kù)鏈接的js文件,可查詢數(shù)據(jù)庫(kù)中的用戶名和密碼等信息 var usr=require('netRequest/dbConnect'); // 獲取首頁(yè)登錄信息 router.get('/', function(req, res) { if(req.cookies.islogin){ req.session.islogin=req.cookies.islogin; } if(req.session.islogin){ res.locals.islogin=req.session.islogin; } res.render('index', { title: 'HOME',test:res.locals.islogin}); }); // 登錄頁(yè)處理 router.route('/login') // get請(qǐng)求渲染頁(yè)面 .get(function(req, res) { if(req.session.islogin){ res.locals.islogin=req.session.islogin; } if(req.cookies.islogin){ req.session.islogin=req.cookies.islogin; } res.render('login', { title: '用戶登錄' ,test:res.locals.islogin}); }) // post請(qǐng)求查詢用戶信息 .post(function(req, res) { client=usr.connect(); result=null; // 調(diào)用數(shù)據(jù)庫(kù)方法 usr.selectFun(client, req.body.username, function (result) { if(result[0]===undefined){ res.send('沒(méi)有該用戶'); }else{ if(result[0].password==req.body.password){ req.session.islogin=req.body.username; res.locals.islogin=req.session.islogin; res.cookie('islogin',res.locals.islogin,{maxAge:60000}); res.redirect('/home'); }else{ res.redirect('/login'); } } }); }); // 退出登錄頁(yè)處理 router.get('/logout', function(req, res) { res.clearCookie('islogin'); req.session.destroy(); res.redirect('/'); }); // home頁(yè)處理 router.get('/home', function(req, res) { if(req.session.islogin){ res.locals.islogin=req.session.islogin; } if(req.cookies.islogin){ req.session.islogin=req.cookies.islogin; } res.render('home', { title: 'Home', user: res.locals.islogin }); }); // 注冊(cè)頁(yè)處理 router.route('/reg') // get請(qǐng)求渲染頁(yè)面 .get(function(req,res){ res.render('reg',{title:'注冊(cè)'}); }) // post請(qǐng)求注冊(cè)用戶 .post(function(req,res) { client = usr.connect(); // 調(diào)用數(shù)據(jù)庫(kù)方法 usr.insertFun(client,req.body.username ,req.body.password2, function (err) { if(err) throw err; res.send('注冊(cè)成功'); }); }); module.exports = router; node_modules中netRequest/dbConnect.js
dbConnect.js
var mysql=require('mysql'); // 現(xiàn)在只是練習(xí)可以直接為數(shù)據(jù)庫(kù)創(chuàng)建鏈接, // 用戶多時(shí)需要?jiǎng)?chuàng)建連接池 function connectServer(){ var client=mysql.createConnection({ host:'172.16.20.103', port:3308, database:'test', user:'JRJ_Win', password:'FT%^$fjYR56' }) return client; } function selectFun(client,username,callback){ client.query('select password from win.luck_user where username="'+username+'"',function(err,results,fields){ if(err) throw err; callback(results); }); } function insertFun(client , username , password,callback){ client.query('insert into win.luck_user value(?,?)', [username, password], function(err,result){ if( err ){ console.log( "error:" + err.message); return err; } callback(err); }); } exports.connect = connectServer; exports.selectFun = selectFun; exports.insertFun = insertFun;
剩下即為頁(yè)面模板
login.ejs
<%- include header %> <div class="container"> <form class="col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post"> <fieldset> <% if(locals.islogin) { %> <h3>用戶: <%= test %> 已經(jīng)登陸。<br></h3> <a class="btn" href="/logout" rel="external nofollow" > 退出登錄 </a> <% } else{ %> <div class="form-group"> <label class="col-sm-3 control-label" for="username">用戶名</label> <div class="col-sm-9"> <input type="text" class="form-control" id="username" name="username" placeholder="用戶名" required> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label" for="password">密碼</label> <div class="col-sm-9"> <input type="password" class="form-control" id="password" name="password" placeholder="密碼" required> </div> </div> <div class="form-group"> <div class="col-sm-offset-3 col-sm-9"> <button type="submit" class="btn btn-primary">登錄</button> </div> </div> <% } %> </fieldset> </form> </div> <%- include footer %>
index.ejs
<%- include header %> <div class="jumbotron text-center"> <% if(locals.islogin){%> <h2>用戶:<%= test %> </h2>已經(jīng)登陸 <% }else{%> <h2 class="text-center"><a href="/login" rel="external nofollow" rel="external nofollow" >請(qǐng)登錄后查看</a></h2> <%}%> </div> <%- include footer %>
reg.ejs
<%- include header %> <div class="container"> <form class=" col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post"> <fieldset> <div class="form-group"> <label class="col-sm-3 control-label" for="username">用戶名</label> <div class="col-sm-9"> <input type="text" class="form-control" id="username" name="username" placeholder="用戶名" required> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label" for="password2">密碼</label> <div class="col-sm-9"> <input type="password" class="form-control" id="password2" name="password2" placeholder="密碼" required> </div> </div> <div class="form-group"> <div class="col-sm-offset-3 col-sm-9"> <button type="submit" class="btn btn-primary">注冊(cè)</button> </div> </div> </fieldset> </form> </div> <%- include footer %>
header.ejs
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>Test</title> <link rel="stylesheet" href="/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="external nofollow" > <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <script type="text/javascript" src="/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <!-- <header> <h1><%= title %></h1> </header> --> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Project name</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >待定</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >待定</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >待定</a></li> <li class="dropdown"> <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">待定<span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Action</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Another action</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Something else here</a></li> <li role="separator" class="divider"></li> <li class="dropdown-header">Nav header</li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Separated link</a></li> <li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >One more separated link</a></li> </ul> </li> </ul> <ul class="nav navbar-nav navbar-right"> <li class="active"><a title="主頁(yè)" href="/" rel="external nofollow" >首頁(yè)<span class="sr-only">(current)</span></a></li> <li><a title="登陸" href="/login" rel="external nofollow" rel="external nofollow" >登錄</a></li> <li><a title="注冊(cè)" href="/reg" rel="external nofollow" >注冊(cè)</a></li> </ul> </div> </nav> <article>
footer.ejs
</article> </body> </html>
項(xiàng)目的主要代碼都在此,想要讀懂的話,估計(jì)要費(fèi)一段時(shí)間的。
總結(jié)
以上所述是小編給大家介紹的node.js+express+mySQL+ejs+bootstrop實(shí)現(xiàn)網(wǎng)站登錄注冊(cè)功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- node.js平臺(tái)下利用cookie實(shí)現(xiàn)記住密碼登陸(Express+Ejs+Mysql)
- 零基礎(chǔ)搭建Node.js、Express、Ejs、Mongodb服務(wù)器及應(yīng)用開(kāi)發(fā)入門
- express框架通過(guò)ejs模板渲染輸出頁(yè)面實(shí)例分析
- Express 框架中使用 EJS 模板引擎并結(jié)合 silly-datetime 庫(kù)進(jìn)行日期格式化的實(shí)現(xiàn)方法
- nodejs中的express-jwt的使用解讀
- NodeJS?Express使用ORM模型訪問(wèn)關(guān)系型數(shù)據(jù)庫(kù)流程詳解
- NodeJs Express框架操作MongoDB數(shù)據(jù)庫(kù)執(zhí)行方法講解
- NodeJs?Express路由使用流程解析
- NodeJs Express中間件使用流程解析
- express框架+bootstrap美化ejs模板實(shí)例分析
相關(guān)文章
JavaScript使用WebSocket實(shí)現(xiàn)實(shí)時(shí)通信的技術(shù)詳解
WebSocket作為一種高效的通信協(xié)議,為開(kāi)發(fā)者提供了一種在客戶端和服務(wù)器之間進(jìn)行全雙工通信的方法,本文將深入探討WebSocket技術(shù),并提供實(shí)戰(zhàn)代碼示例2024-04-04websocket4.0+typescript 實(shí)現(xiàn)熱更新的方法
這篇文章主要介紹了websocket4.0+typescript 實(shí)現(xiàn)熱更新的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08js屬性對(duì)象的hasOwnProperty方法的使用
這篇文章主要介紹了js屬性對(duì)象的hasOwnProperty方法的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射
這篇文章主要介紹了如何用threejs實(shí)現(xiàn)實(shí)時(shí)多邊形折射,對(duì)three.js庫(kù)感興趣的同學(xué),可以參考下2021-05-05基于JS實(shí)現(xiàn)仿京東搜索欄隨滑動(dòng)透明度漸變效果
這篇文章主要介紹了基于JS實(shí)現(xiàn)仿京東搜索欄隨滑動(dòng)透明度漸變效果,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-07-07JavaScript 異步方法隊(duì)列鏈實(shí)現(xiàn)代碼分析
在javascript中,方法的鏈?zhǔn)秸{(diào)用很流行,使用jQuery的朋友對(duì)此一定深有體會(huì)。2010-06-06新手學(xué)習(xí)前端之js模仿淘寶主頁(yè)網(wǎng)站
淘寶網(wǎng)大家在熟悉不過(guò)了,那么淘寶網(wǎng)首頁(yè)模板是怎么做的呢?今天小編抽時(shí)間給大家分享新手學(xué)習(xí)前端之js模仿淘寶主頁(yè)網(wǎng)站的相關(guān)資料,需要的朋友可以參考下2016-10-10