javascript
NodeJS学习笔记(一)——搭建开发框架Express,实现Web网站登录验证
?
目錄
- 開發環境
- 1、建立工程
- 2、目錄結構
- 3、Express配置文件
- 4、Ejs模板
- 5、安裝常用庫及頁面分離
- 6、路由
- 7、session
- 8、頁面訪問控制及提示
JS是腳本語言,腳本語言都需要一個解析器才能運行。對于寫在HTML頁面里 的JS,瀏覽器充當了解析器的角色。而對于需要獨立運行的JS,NodeJS就是一個解析器。每一種解析器都是一個運行環境,不但允許JS定義各種數據結 構,進行各種計算,還允許JS使用運行環境提供的內置對象和方法做一些事情。例如運行在瀏覽器中的JS的用途是操作DOM,瀏覽器就提供了 document之類的內置對象。而運行在NodeJS中的JS的用途是操作磁盤文件或搭建HTTP服務器,NodeJS就相應提供了fs、http等內 置對象。Express作為NodeJS的Web應用框架,可以幫助我們快速開發Web網站。
開發環境
- NodeJS:v0.10.30
- npm:1.4.21
- OS:Win7旗艦版 32bit
- Express:4.2.0
- MongoDB:2.6.3
1 2 E:\project> node -v v0.10.30 E:\project> npm -v 1.4.21 E:\project> express -V 4.2.0 ?
?
1、建立工程
使用express命令建立工程,并支持ejs:
?
根據提示下載依賴包:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | E:\project> cd .\nodejs-demo E:\project\nodejs-demo> npm install npm WARN deprecated static-favicon@1.0.2: use serve-favicon module static-favicon@1.0.2 node_modules\static-favicon debug@0.7.4 node_modules\debug ejs@0.8.8 node_modules\ejs cookie-parser@1.0.1 node_modules\cookie-parser ├── cookie-signature@1.0.3 └── cookie@0.1.0 morgan@1.0.1 node_modules\morgan └── bytes@0.3.0 body-parser@1.0.2 node_modules\body-parser ├── qs@0.6.6 ├── raw-body@1.1.7 (bytes@1.0.0, string_decoder@0.10.25-1) └── type-is@1.1.0 (mime@1.2.11) express@4.2.0 node_modules\express ├── parseurl@1.0.1 ├── utils-merge@1.0.0 ├── cookie@0.1.2 ├── merge-descriptors@0.0.2 ├── escape-html@1.0.1 ├── range-parser@1.0.0 ├── fresh@0.2.2 ├── cookie-signature@1.0.3 ├── debug@0.8.1 ├── methods@1.0.0 ├── buffer-crc32@0.2.1 ├── serve-static@1.1.0 ├── path-to-regexp@0.1.2 ├── qs@0.6.6 ├── send@0.3.0 (debug@0.8.0, mime@1.2.11) ├── accepts@1.0.1 (negotiator@0.4.7, mime@1.2.11) └── type-is@1.1.0 (mime@1.2.11) E:\project\nodejs-demo> |
?
?
工程建立成功,啟動服務:
| 1 | E:\project\nodejs-demo> npm start > nodejs-demo@0.0.1 start E:\project\nodejs-demo > node ./bin/www |
?
?
?
本地3000端口被打開,在瀏覽器地址欄輸入localhost:3000,訪問成功。
2、目錄結構
- bin——存放命令行程序。
- node_modules——存放所有的項目依賴庫。
- public——存放靜態文件,包括css、js、img等。
- routes——存放路由文件。
- views——存放頁面文件(ejs模板)。
- app.js——程序啟動文件。
- package.json——項目依賴配置及開發者信息。
| 1 2 3 4 5 6 7 8 9 10 11 | E:\project\nodejs-demo> dir ????目錄: E:\project\nodejs-demo Mode??????????????? LastWriteTime???? Length Name ----??????????????? -------------???? ------ ---- d----???????? 2014/8/16???? 21:55 bin d----???????? 2014/8/16???? 22:03 node_modules d----???????? 2014/8/16???? 21:55 public d----???????? 2014/8/16???? 21:55 routes d----???????? 2014/8/16???? 21:55 views -a---???????? 2014/8/16???? 21:55?????? 1375 app.js -a---???????? 2014/8/16???? 21:55??????? 327 package.json |
?
?
3、Express配置文件
打開app.js:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | var express = require('express'); var path = require('path'); var favicon = require('static-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(favicon()); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); /// 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 handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { ????app.use(function(err, req, res, next) { ????????res.status(err.status || 500); ????????res.render('error', { ????????????message: err.message, ????????????error: err ????????}); ????}); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { ????res.status(err.status || 500); ????res.render('error', { ????????message: err.message, ????????error: {} ????}); }); module.exports = app; |
?
?
4、Ejs模板
修改app.js,讓ejs模板文件使用擴展名為html的文件:
| 1 2 3 4 5 | 13 // view engine setup 14 app.set('views', path.join(__dirname, 'views')); 15 //app.set('view engine', 'ejs'); 16 app.engine('html', require('ejs').renderFile); 17 app.set('view engine', 'html'); |
?
?
?
修改完成后,重命名views/index.ejs為views/index.html。重啟服務,訪問成功。
5、安裝常用庫及頁面分離
添加bootstrap和jQuery:
E:\project\nodejs-demo> npm install bootstrap bootstrap@3.2.0 node_modules\bootstrap E:\project\nodejs-demo> npm install jquery jquery@2.1.1 node_modules\jquery E:\project\nodejs-demo>接下來,把index.html分成三個部分:
- header.html——頁面頭部區域。
- index.html——頁面內容區域。
- footer.html——頁面底部區域。
header.html
| 1 2 3 4 5 6 7 8 9 | <!DOCTYPE html> <html lang="en"> <head> ????<meta charset="utf-8"> ????<title><%= title %></title> ????<!-- Bootstrap --> ????<link href="/stylesheets/bootstrap.min.css" rel="stylesheet" media="screen"> </head> <body screen_capture_injected="true"> |
?
?
index.html
| 1 2 3 4 | 1 <% include header.html %> 2 <h1><%= title %></h1> 3 <p>Welcome to <%= title %></p> 4 <% include footer.html %> |
?
?
footer.html?
| 1 2 3 4 5 6 | <script src="/javascripts/jquery.min.js"></script> ?<script src="/javascripts/bootstrap.min.js"></script> ?</body> ?</html> |
?
?
?
重啟服務,訪問成功。
6、路由
登錄設計:
| 訪問路徑 | 頁面 | 描述 |
| / | index.html | 不需要登錄,可以直接訪問。 |
| /home | home.html | 必須用戶登錄以后,才可以訪問。 |
| /login | login.html | 登錄頁面,用戶名密碼輸入正確,自動跳轉到home.html。 |
| /logout | 無 | 退出登錄后,自動跳轉到index.html。 |
打開app.js文件,增加路由配置:
| 1 2 3 4 5 | 26 app.use('/', routes); 27 app.use('/users', users); 28 app.use('/login', routes); 29 app.use('/logout', routes); 30 app.use('/home', routes); |
?
?
打開routes/index.js文件,添加對應方法:| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) { ??res.render('index', { title: 'Express' }); }); router.route('/login') .get(function(req, res) { ????res.render('login', { title: '用戶登錄' }); }) .post(function(req, res) { ????var user={ ????????username: 'admin', ????????password: '123456' ????} ????if(req.body.username === user.username && req.body.password === user.password){ ????????res.redirect('/home'); ????} ????res.redirect('/login'); }); router.get('/logout', function(req, res) { ????res.redirect('/'); }); router.get('/home', function(req, res) { ????var user={ ????????username:'admin', ????????password:'123456' ????} ????res.render('home', { title: 'Home', user: user }); }); module.exports = router; |
?
?
創建views/login.html和views/home.html兩個文件:
login.html
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <% include header.html %> <div class="container"> ????<form class="col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post"> ????????<fieldset> ????????????<legend>用戶登錄</legend> ????????????<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.html %> |
?
?
home.html
| 1 2 3 4 | 1 <% include header.html %> 2 <h1>Welcome <%= user.username %>, 歡迎登錄!!</h1> 3 <a class="btn" href="/logout">退出</a> 4 <% include footer.html %> |
?
?
修改index.html,增加登錄鏈接:
?
| 1 2 3 4 | 1 <% include header.html %> 2???? <h1>Welcome to <%= title %></h1> 3???? <p><a href="/login">登錄</a></p> 4 <% include footer.html %> |
?
?
路由及頁面已準備好,重啟服務,訪問成功。?
7、session
安裝中間件express-session:
| 1 2 3 4 5 | E:\project\nodejs-demo> npm install express-session express-session@1.7.5 node_modules\express-session ├── cookie@0.1.2 ├── cookie-signature@1.0.4 ├── on-headers@1.0.0 ├── utils-merge@1.0.0 ├── parseurl@1.3.0 ├── buffer-crc32@0.2.3 ├── depd@0.4.4 ├── debug@1.0.4 (ms@0.6.2) └── uid-safe@1.0.1 (base64-url@1.0.0, mz@1.0.0) E:\project\nodejs-demo> |
?
?
安裝中間件connect-mongodb:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | E:\project\nodejs-demo> npm install connect-mongodb \ > kerberos@0.0.3 install E:\project\nodejs-demo\node_modules\connect-mongodb\nod e_modules\mongodb\node_modules\kerberos > (node-gyp rebuild 2> builderror.log) || (exit 0) | E:\project\nodejs-demo\node_modules\connect-mongodb\node_modules\mongodb\node_mo dules\kerberos>node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\ ..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild | > bson@0.2.11 install E:\project\nodejs-demo\node_modules\connect-mongodb\node_m odules\mongodb\node_modules\bson > (node-gyp rebuild 2> builderror.log) || (exit 0) E:\project\nodejs-demo\node_modules\connect-mongodb\node_modules\mongodb\node_mo dules\bson>node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\. .\node_modules\node-gyp\bin\node-gyp.js" rebuild connect-mongodb@1.1.5 node_modules\connect-mongodb ├── connect@1.9.2 (mime@1.2.11, formidable@1.0.15, qs@1.2.2) └── mongodb@1.4.8 (kerberos@0.0.3, readable-stream@1.0.27-1, bson@0.2.11) E:\project\nodejs-demo> |
?
?
安裝中間件mongodb:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | E:\project\nodejs-demo> npm install mongodb - > kerberos@0.0.3 install E:\project\nodejs-demo\node_modules\mongodb\node_module s\kerberos > (node-gyp rebuild 2> builderror.log) || (exit 0) - E:\project\nodejs-demo\node_modules\mongodb\node_modules\kerberos>node "C:\Progr am Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\b in\node-gyp.js" rebuild | > bson@0.2.11 install E:\project\nodejs-demo\node_modules\mongodb\node_modules\b son > (node-gyp rebuild 2> builderror.log) || (exit 0) E:\project\nodejs-demo\node_modules\mongodb\node_modules\bson>node "C:\Program F iles\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\n ode-gyp.js" rebuild mongodb@1.4.8 node_modules\mongodb ├── kerberos@0.0.3 ├── readable-stream@1.0.27-1 (isarray@0.0.1, string_decoder@0.10.25-1, inheri ts@2.0.1, core-util-is@1.0.1) └── bson@0.2.11 (nan@1.2.0) E:\project\nodejs-demo> |
?
?
添加database/settings.js和database/msession.js這兩個文件:
settings.js
| 1 2 3 4 5 6 7 8 9 | module.exports = { ????COOKIE_SECRET: 'ywang1724.com', ????URL: 'mongodb://127.0.0.1:27017/nodedb', ????DB: 'nodedb', ????HOST: '127.0.0.1', ????PORT: 27017, ????USERNAME: 'admin', ????PASSWORD: '123456' }; |
?
?
msession.js
?
| 1 2 3 4 5 6 | 1 var Settings = require('./settings'); 2 var Db = require('mongodb').Db; 3 var Server = require('mongodb').Server; 4 var db = new Db(Settings.DB, new Server(Settings.HOST, Settings.PORT, {auto_reconnect:true, native_parser: true}),{safe: false}); 5 6 module.exports = db; |
?
?
?
修改app.js文件:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | var express = require('express'); var path = require('path'); var favicon = require('static-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); //采用connect-mongodb中間件作為Session存儲? var session = require('express-session');? var Settings = require('./database/settings');? var MongoStore = require('connect-mongodb');? var db = require('./database/msession'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); //app.set('view engine', 'ejs'); app.engine('html', require('ejs').renderFile); app.set('view engine', 'html'); app.use(favicon()); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); app.use(cookieParser()); //session配置 app.use(session({ ????cookie: { maxAge: 600000 }, ????secret: Settings.COOKIE_SECRET, ????store: new MongoStore({? ????????username: Settings.USERNAME, ????????password: Settings.PASSWORD, ????????url: Settings.URL, ????????db: db}) })) app.use(function(req, res, next){ ????res.locals.user = req.session.user; ????next(); }); app.use(express.static(path.join(__dirname, 'public'))); ...... |
?
?
修改index.js文件:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) { ????res.render('index', { title: 'Express' }); }); router.route('/login') .get(function(req, res) { ????res.render('login', { title: '用戶登錄' }); }) .post(function(req, res) { ????var user = { ????????username: 'admin', ????????password: '123456' ????} ????if(req.body.username === user.username && req.body.password === user.password){ ????????req.session.user = user; ????????res.redirect('/home'); ????} else { ????????res.redirect('/login'); ????} }); router.get('/logout', function(req, res) { ????req.session.user = null; ????res.redirect('/'); }); router.get('/home', function(req, res) { ????res.render('home', { title: 'Home' }); }); module.exports = router; |
?
?
本地安裝數據庫MongoDB,新建用戶nodedb。重啟服務,訪問成功。
8、頁面訪問控制及提示
訪問控制設計:
| 訪問路徑 | 描述 |
| / | 任何人都可以訪問,不需要認證。 |
| /home | 攔截get請求,調用authentication()進行認證,不通過則自動跳轉到登錄頁面。 |
| /login | 任何人都可以訪問,不需要認證。 |
| /logout | 任何人都可以訪問,不需要認證。 |
修改index.js文件:
| 1 2 3 4 5 6 7 8 9 10 | router.get('/home', function(req, res) { ????authentication(req, res); ????res.render('home', { title: 'Home' }); }); function authentication(req, res) { ????if (!req.session.user) { ????????return res.redirect('/login'); ????} } |
?
?
重啟服務,訪問成功。
添加頁面提示,修改app.js文件,增加res.locals.message:
| 1 2 3 4 5 6 7 8 9 10 | app.use(function(req, res, next) { ????res.locals.user = req.session.user; ????var err = req.session.error; ????delete req.session.error; ????res.locals.message = ''; ????if (err) { ????????res.locals.message = '<div class="alert alert-warning">' + err + '</div>'; ????} ????next(); }); |
?
?
修改index.js文件,增加req.session.error:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) { ????res.render('index', { title: 'Express' }); }); router.route('/login') .get(function(req, res) { ????if (req.session.user) { ????????res.redirect('/home'); ????} ????res.render('login', { title: '用戶登錄' }); }) .post(function(req, res) { ????var user = { ????????username: 'admin', ????????password: '123456' ????} ????if (req.body.username === user.username && req.body.password === user.password) { ????????req.session.user = user; ????????res.redirect('/home'); ????} else { ????????req.session.error='用戶名或密碼不正確'; ????????res.redirect('/login'); ????} }); router.get('/logout', function(req, res) { ????req.session.user = null; ????res.redirect('/'); }); router.get('/home', function(req, res) { ????authentication(req, res); ????res.render('home', { title: 'Home' }); }); function authentication(req, res) { ????if (!req.session.user) { ????????req.session.error='請先登錄'; ????????return res.redirect('/login'); ????} } module.exports = router; |
?
?
修改login.html,增加<%- message %>:
?
| 1 2 3 | 5 <legend>用戶登錄</legend> 6 <%- message %> 7 <div class="form-group"> |
?
?
?
重啟服務,訪問成功。輸入錯誤用戶名密碼:
轉載于:https://www.cnblogs.com/winyh/p/6681422.html
總結
以上是生活随笔為你收集整理的NodeJS学习笔记(一)——搭建开发框架Express,实现Web网站登录验证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用showMessageDialog显
- 下一篇: BFS(广度优先搜索)