搭建開發框架Express,實現Web網站登入驗證
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
E:\project> node -v v0.10.30 E:\project> npm -v 1.4.21 E:\project> express -V 4.2.0
1、建立工程
使用express命令建立工程,並支援ejs:
E:\project> express -e nodejs-demo create : nodejs-demo create : nodejs-demo/package.json create : nodejs-demo/app.js create : nodejs-demo/public create : nodejs-demo/public/javascripts create : nodejs-demo/public/images create : nodejs-demo/public/stylesheets create : nodejs-demo/public/stylesheets/style.css create : nodejs-demo/routes create : nodejs-demo/routes/index.js create : nodejs-demo/routes/users.js create : nodejs-demo/views create : nodejs-demo/views/index.ejs create : nodejs-demo/views/error.ejs create : nodejs-demo/bin create : nodejs-demo/bin/www install dependencies: $ cd nodejs-demo && npm install run the app: $ DEBUG=nodejs-demo ./bin/www E:\project>
根據提示下載依賴包:
E:\project> cd .\nodejs-demo E:\project\nodejs-demo> npm install npm WARN deprecated static[email protected]: use serve-favicon module static[email protected] node_modules\static-favicon debug@0.7.4 node_modules\debug ejs@0.8.8 node_modules\ejs cookie[email protected] node_modules\cookie-parser ├── cookie[email protected] └── cookie@0.1.0 morgan@1.0.1 node_modules\morgan └── bytes@0.3.0 body[email protected] node_modules\body-parser ├── qs@0.6.6 ├── raw[email protected] ([email protected], [email protected]) └── type-is@1.1.0 ([email protected]) express@4.2.0 node_modules\express ├── parseurl@1.0.1 ├── utils[email protected] ├── cookie@0.1.2 ├── merge[email protected] ├── escape[email protected] ├── range[email protected] ├── fresh@0.2.2 ├── cookie[email protected] ├── debug@0.8.1 ├── methods@1.0.0 ├── buffer[email protected] ├── serve[email protected] ├── path[email protected] ├── qs@0.6.6 ├── send@0.3.0 ([email protected], [email protected]) ├── accepts@1.0.1 ([email protected], [email protected]) └── type-is@1.1.0 ([email protected]) E:\project\nodejs-demo>
工程建立成功,啟動服務:
E:\project\nodejs-demo> npm start > [email protected] 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——專案依賴配置及開發者資訊。
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 var express = require('express'); 2 var path = require('path'); 3 var favicon = require('static-favicon'); 4 var logger = require('morgan'); 5 var cookieParser = require('cookie-parser'); 6 var bodyParser = require('body-parser'); 7 8 var routes = require('./routes/index'); 9 var users = require('./routes/users'); 10 11 var app = express(); 12 13 // view engine setup 14 app.set('views', path.join(__dirname, 'views')); 15 app.set('view engine', 'ejs'); 16 17 app.use(favicon()); 18 app.use(logger('dev')); 19 app.use(bodyParser.json()); 20 app.use(bodyParser.urlencoded()); 21 app.use(cookieParser()); 22 app.use(express.static(path.join(__dirname, 'public'))); 23 24 app.use('/', routes); 25 app.use('/users', users); 26 27 /// catch 404 and forward to error handler 28 app.use(function(req, res, next) { 29 var err = new Error('Not Found'); 30 err.status = 404; 31 next(err); 32 }); 33 34 /// error handlers 35 36 // development error handler 37 // will print stacktrace 38 if (app.get('env') === 'development') { 39 app.use(function(err, req, res, next) { 40 res.status(err.status || 500); 41 res.render('error', { 42 message: err.message, 43 error: err 44 }); 45 }); 46 } 47 48 // production error handler 49 // no stacktraces leaked to user 50 app.use(function(err, req, res, next) { 51 res.status(err.status || 500); 52 res.render('error', { 53 message: err.message, 54 error: {} 55 }); 56 }); 57 58 59 module.exports = app;
4、Ejs模板
修改app.js,讓ejs模板檔案使用副檔名為html的檔案:
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 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <title><%= title %></title> 6 <!-- Bootstrap --> 7 <link href="/stylesheets/bootstrap.min.css" rel="stylesheet" media="screen"> 8 </head> 9 <body screen_capture_injected="true">
index.html
1 <% include header.html %> 2 <h1><%= title %></h1> 3 <p>Welcome to <%= title %></p> 4 <% include footer.html %>
footer.html
1 <script src="/javascripts/jquery.min.js"></script> 2 <script src="/javascripts/bootstrap.min.js"></script> 3 </body> 4 </html>
重啟服務,訪問成功。
6、路由
登入設計:
訪問路徑 | 頁面 | 描述 |
/ | index.html | 不需要登入,可以直接訪問。 |
/home | home.html | 必須使用者登入以後,才可以訪問。 |
/login | login.html | 登入頁面,使用者名稱密碼輸入正確,自動跳轉到home.html。 |
/logout | 無 | 退出登入後,自動跳轉到index.html。 |
開啟app.js檔案,增加路由配置:
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 var express = require('express'); 2 var router = express.Router(); 3 4 /* GET home page. */ 5 router.get('/', function(req, res) { 6 res.render('index', { title: 'Express' }); 7 }); 8 9 router.route('/login') 10 .get(function(req, res) { 11 res.render('login', { title: '使用者登入' }); 12 }) 13 .post(function(req, res) { 14 var user={ 15 username: 'admin', 16 password: '123456' 17 } 18 if(req.body.username === user.username && req.body.password === user.password){ 19 res.redirect('/home'); 20 } 21 res.redirect('/login'); 22 }); 23 24 router.get('/logout', function(req, res) { 25 res.redirect('/'); 26 }); 27 28 router.get('/home', function(req, res) { 29 var user={ 30 username:'admin', 31 password:'123456' 32 } 33 res.render('home', { title: 'Home', user: user }); 34 }); 35 36 module.exports = router;
建立views/login.html和views/home.html兩個檔案:
login.html
1 <% include header.html %> 2 <div class="container"> 3 <form class="col-sm-offset-4 col-sm-4 form-horizontal" role="form" method="post"> 4 <fieldset> 5 <legend>使用者登入</legend> 6 <div class="form-group"> 7 <label class="col-sm-3 control-label" for="username">使用者名稱</label> 8 <div class="col-sm-9"> 9 <input type="text" class="form-control" id="username" name="username" placeholder="使用者名稱" required> 10 </div> 11 </div> 12 <div class="form-group"> 13 <label class="col-sm-3 control-label" for="password">密碼</label> 14 <div class="col-sm-9"> 15 <input type="password" class="form-control" id="password" name="password" placeholder="密碼" required> 16 </div> 17 </div> 18 <div class="form-group"> 19 <div class="col-sm-offset-3 col-sm-9"> 20 <button type="submit" class="btn btn-primary">登入</button> 21 </div> 22 </div> 23 </fieldset> 24 </form> 25 </div> 26 <% include footer.html %>
home.html
1 <% include header.html %> 2 <h1>Welcome <%= user.username %>, 歡迎登入!!</h1> 3 <a class="btn" href="/logout">退出</a> 4 <% include footer.html %>
修改index.html,增加登入連結:
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:
E:\project\nodejs-demo> npm install express-session express[email protected] node_modules\express-session ├── cookie@0.1.2 ├── cookie[email protected] ├── on[email protected] ├── utils[email protected] ├── parseurl@1.3.0 ├── buffer[email protected] ├── depd@0.4.4 ├── debug@1.0.4 ([email protected]) └── uid