目錄
前言
前面經過五篇Node.js的學習,基本可以開始動手構建一個網站應用了,先用這一篇了解一些構建網站的知識!
主要是些基礎的東西...
如何去創建路由規則、如何去提交表單並接收表單項的值、如何去給密碼加密、如何去提取頁面公共部分(相當於用戶控件和母版頁)等等...
下面就一步步開始吧^_^!...
新建express項目並自定義路由規則
1.首先用命令行express+ejs創建一個項目sampleEjsPre
cd 工作目錄 express -e sampleEjsPre cd sampleEjsPre && npm install
2.默認會有routes目錄下會有index.js和users.js文件,這里為了不產生其它示例外的困擾,刪除user.js文件
3.打開app.js文件刪除下面兩行代碼
var users = require('./routes/users'); ... app.use('/users', users);
4.在app.js文件中添加如下代碼
var subform = require('./routes/subform'); var usesession = require('./routes/usesession'); var usecookies = require('./routes/usecookies'); var usecrypto = require('./routes/usecrypto'); ... app.use('/subform', subform); app.use('/usesession', usesession); app.use('/usecookies', usecookies); app.use('/usecrypto', usecrypto);
通過URL訪問后,根據路由規則先到哪個文件,再到哪個文件的過程在上一篇文章(Nodejs學習筆記(五)--- Express安裝入門與模版引擎ejs)中有說到,這里就不多說了!
5.在routes目錄下添加subform.js、usesession.js、usecookies.js、usecrypto.js文件,並在對應的js文件中添加如下代碼

var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) { res.render('subform', { title: '提交表單及接收參數示例' }); }); module.exports = router;

var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) { res.render('usesession', { title: '使用session示例' }); }); module.exports = router;

var express = require('express'); var router = express.Router(); router.get('/', function(req, res) { res.render('usecookies', { title: '使用cookies示例' }); }); module.exports = router;

var express = require('express'); var router = express.Router(); router.get('/', function(req, res) { res.render('usecrypto', { title: '加密字符串示例' }); }); module.exports = router;
6.在views目錄下添加subform.ejs、usesession.ejs、usecookies.ejs、usecrypto.ejs文件,並在views目錄下除了error.ejs外所有ejs文件中添加如下代碼
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <a href="/">首頁</a> <a href="/subform">如何提交表單並接收參數?</a> <a href="/usesession">如何使用session?</a> <a href="/usecookies">如何使用cookies?</a> <a href="/usecrypto">如何字符串加密?</a> </body> </html>
7.在app.js中添加8000端口監聽並運行
... app.listen(8000); ...
運行界面如下:
點擊各鏈接都能正常跳轉到對應的頁面!這樣第一步的目錄就算達到了!
如何提取頁面中的公共部分?
在上一步創建的網站中每個頁面都幾乎一樣,現在都只有導航部分?每個頁都要寫?當然不是,我們可以提取出來
1.在views目錄下新建一個nav.ejs文件,並添加如下代碼
<a href="/">首頁</a> <a href="/subform">如何提交表單並接收參數?</a> <a href="/usesession">如何使用session?</a> <a href="/usecookies">如何使用cookies?</a> <a href="/usecrypto">如何字符串加密?</a>
2.把views目錄下index.ejs、subform.ejs、usesession.ejs、usecookies.ejs、usecrypto.ejs修改成如下代碼
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <% include nav %> </body> </html>
運行頁面,發現和上次運行時沒有作何區別,有了這樣的辦法更有利於減少重復代碼、也更有利於統一布局!
<% include 文件名 %> express提供include來嵌入其它頁,這和html嵌入其它頁類似
如果用過express2.0版本的會發現當時沒有這個include,用的是一個模版文件layout.ejs來布局!
如何提交表單並接收參數?
如果要做一個網站應用,不可避免的會遇到表單的提交及獲取參數的值,下面我們來看看用node.js + express怎么做
1.打開subform.ejs文件,修改文件代碼為如下:

<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <% include nav %> <form> 用戶名:<input type="text" id="txtUserName" name="txtUserName" /> 密碼:<input type="password" id="txtUserPwd" name="txtUserPwd" /> <input type="submit" value="提交"> </form> </body> </html>
2.打開subform.js我們試着接收參數值並輸出到控制台

var express = require('express'); var router = express.Router(); router.get('/', function(req, res) { var userName = req.query.txtUserName, userPwd = req.query.txtUserPwd, userName2 = req.param('txtUserName'), userPwd2 = req.param('txtUserPwd'); console.log('req.query用戶名:'+userName); console.log('req.query密碼:'+userPwd); console.log('req.param用戶名:'+userName2); console.log('req.param密碼:'+userPwd2); res.render('subform', { title: '提交表單及接收參數示例' }); }); module.exports = router;
3.運行,並提交表單 在瀏覽器中運行:http://localhost:8000/subform,輸入表單項並提交,可以發現url發生了變化
可以發現url中出現了我表單中輸入並要提交的值!
我們再看看控制台的輸出
我們完成了GET方式提交表單並接收到了值,不錯^_^!(稍后在后面再去講得到值的方式和區別)
再來在上面的代碼基礎上去修改一下表單的method簡單模擬登錄POST方式提交數據
1.首先修改一下subform.ejs文件中的form標簽,修改為如下:
<form method="post"> ... </form>
2.再在subform.js中添加代碼,接收post提交、接收參數並輸出到控制台
... router.post('/',function(req, res){ var userName = req.body.txtUserName, userPwd = req.body.txtUserPwd, userName2 = req.param('txtUserName'), userPwd2 = req.param('txtUserPwd'); console.log('req.body用戶名:'+userName); console.log('req.body密碼:'+userPwd); console.log('req.param用戶名:'+userName2); console.log('req.param密碼:'+userPwd2);
res.render('subform', { title: '提交表單及接收參數示例' }); }); ...
3.運行,並提交表單 在瀏覽器中運行:http://localhost:8000/subform,輸入表單項並提交,可以發現url不會發生變化
改為post方式后,會發現不會跟get方式提交一樣在url中出現了表單中輸入並要提交的值!
我們再看看控制台的輸出
OK,我們完成了POST提交表單並接收參數!
再回過頭看看GET和POST方式接收值,從直接效果上來看
req.query:我用來接收GET方式提交參數
req.body:我用來接收POST提交的參數
req.params:兩種都能接收到
大家自行看看Express的Request部分的API: http://expressjs.com/api.html#req.params
這里着重解釋一下req.body,Express處理這個post請求是通過中間件bodyParser,你可以看到app.js中有一塊代碼
... var bodyParser = require('body-parser'); ... app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); ...
沒有這個中間件Express就不知道怎么處理這個請求,通過bodyParser中間件分析 application/x-www-form-urlencoded和application/json請求,並把變量存入req.body,這種我們才能夠獲取到!
如何字符串加密?
當我們提交表單后,比如密碼這些敏感信息,不做個加密處理那也太不把用戶私密信息當回事了,Node.js提供了一個加密模塊 Crypto http://nodejs.org/api/crypto.html
下面我們用個示例使用一下
1.打開usecrypto.js,修改代碼為如下:
var express = require('express'); var router = express.Router(); var crypto = require('crypto'); /* GET home page. */ router.get('/', function(req, res) { res.render('usecrypto', { title: '加密字符串示例' }); }); router.post('/',function(req, res){ var userName = req.body.txtUserName, userPwd = req.body.txtUserPwd; //生成口令的散列值 var md5 = crypto.createHash('md5'); //crypto模塊功能是加密並生成各種散列 var en_upwd = md5.update(userPwd).digest('hex'); console.log('加密后的密碼:'+en_upwd); res.render('usecrypto', { title: '加密字符串示例' }); }); module.exports = router;
2.打開usecrypto.ejs,修改代碼為如下
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <% include nav %> <form method="post"> 用戶名:<input type="text" id="txtUserName" name="txtUserName" /> 密碼:<input type="password" id="txtUserPwd" name="txtUserPwd" /> <input type="submit" value="提交"> </form> </body> </html>
3.運行,輸入並提交表單,查看控件台輸出
成功MD5方式加密!
其中用到了createHash(algorithm)方法 ,這是利用給定的算法生成hash對象
Node.js提供的加密模塊功能非常強大,Hash算法就提供了MD5、sha1、sha256等,根據需要去使用
update(data, [input_encoding])方法,可以通過指定的input_encoding和傳入的data數據更新hash對象,input_encoding為可選參數,沒有傳入則作為buffer處理 (input_encoding可為'utf-8'、'ascii'等)
digest([encoding])方法,計算數據的hash摘要值,encoding是可選參數,不傳則返回buffer (encoding可為 'hex'、'base64'等);當調用digest方法后hash對象將不可用;
如何使用session?
Internet通訊協議分為stateful和stateless兩類,對Web開發有一定了解的應該知道,http是stateless協議,客戶端發送請求到服務端建立一個連接,請求得得到響應后連接即中斷,服務器端不會記錄狀態,因此服務器端想
要確定是哪個客戶端提交過來的請求,那就必須要借助一些東西去完成,就是session和cookies,現在我們先說說session,以及在nodejs下使用session !
session存在於服務器端,需要cookies的協助才能完成;服務器端和客戶端通過session id來建立聯系(具體session和cookies怎么協作的,可以自已去補充點相關知識,這里只簡單提一下,不展開了,要不然這篇文章就更雜了^_^!)
express中可以用中間件來使用session,express-session( https://github.com/expressjs/session ) 可以存在內存中,也可以存在mongodb、redis等中...
更多中間件:https://github.com/senchalabs/connect#middleware
下面我們通過示例看看怎么使用session (內存方式)
示例設計思路:使用兩個頁面,一個登錄,兩個頁都判斷是否有這個session,如果有,顯示已登錄,沒有則顯示一個登錄按鈕,點此按鈕,記錄session
1.首先通過npm安裝這個中間件,打開package.json文件,在dependencies節點下添加一個鍵值對 "express-session" : "latest"
"dependencies": { ..., "express-session" : "latest" }
lateset:最新的
2. cd到項目根目錄下,執行npm install
3.打開app.js,添加如下代碼
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 session = require('express-session'); ... //這里傳入了一個密鑰加session id app.use(cookieParser('Wilson'));
//使用靠就這個中間件 app.use(session({ secret: 'wilson'})); ...
這些options就不解釋了,通過上面中間件的鏈接,自已看一下
4.我這里使用usesession和usecookies作示例,修改js和ejs如下

<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <% include nav %> <% if(locals.islogin){ %> 用戶已登錄 <% } else { %> <form method="post"> <input type="submit" value="登錄"> </form> <% } %> </body> </html>

var express = require('express'); var router = express.Router(); router.get('/', function(req, res) { if(req.session.islogin) { console.log('usesession:' + req.session.islogin); res.locals.islogin = req.session.islogin; } res.render('usesession', { title: '使用session示例' }); }); router.post('/', function(req, res) { req.session.islogin = 'success'; res.locals.islogin = req.session.islogin; res.render('usesession', { title: '使用session示例' }); }); module.exports = router;

var express = require('express'); var router = express.Router(); router.get('/', function(req, res) { if(req.session.islogin) { console.log('usecookies:' + req.session.islogin); res.locals.islogin = req.session.islogin; } res.render('usecookies', { title: '使用cookies示例' }); }); router.post('/', function(req, res) { req.session.islogin = 'success'; res.locals.islogin = req.session.islogin; res.render('usecookies', { title: '使用cookies示例' }); }); module.exports = router;
5.運行並查看
第一次運行時,查看兩個頁,效果如下:
6.點擊登錄按鈕后,再查看這兩個頁
7.關閉瀏覽器,再打開查看這兩個頁,如第5步截圖效果
session的使用成功!
官方示例:https://github.com/visionmedia/express/blob/master/examples/session/index.js
如何使用cookies?
如果是登錄,那常見就是“記錄密碼”或“自動登錄”功能,這個一般用 cookies來完成
cookies存在客戶端,安全性較低,一般要存入加密后的信息;建議要設置使用過期時間或不使用時刪除掉
express也同樣可以用中間件來使用:https://github.com/expressjs/cookie-parser
老套路,通過一個示例了解一下
示例設計思路:在上面session示例的基礎上,在usecookies部分登錄同時記錄cookies,來自動登錄
1.在上面session示例的基礎上修改一下usecookies.js
var express = require('express'); var router = express.Router(); router.get('/', function(req, res) { if(req.cookies.islogin) { console.log('usecookies-cookies:' + req.cookies.islogin); req.session.islogin = req.cookies.islogin; } if(req.session.islogin) { console.log('usecookies:' + req.session.islogin); res.locals.islogin = req.session.islogin; } res.render('usecookies', { title: '使用cookies示例' }); }); router.post('/', function(req, res) { req.session.islogin = 'success'; res.locals.islogin = req.session.islogin; res.cookie('islogin', 'sucess', { maxAge: 60000 }); res.render('usecookies', { title: '使用cookies示例' }); }); module.exports = router;
2.運行訪問 http://localhost:8000/usecookies,點擊登錄按鈕登錄成功並記錄cookies
maxAge為過期時長,毫秒為單位,我設置一分鍾
3.關閉瀏覽器,再次訪問http://localhost:8000/usecookies ,頁面顯示已登錄
4.再次關閉瀏覽器,過一分鍾再訪問http://localhost:8000/usecookies,頁面不再是已登錄,而是顯示登錄按鈕,表示cookies過期,不會自動登錄
cookies的使用到此也成功!
官方示例:https://github.com/visionmedia/express/blob/master/examples/cookies/app.js
如何清除session和cookies?
清除非常簡單,就不用示例說明了,有興趣自已定義個路由規則,試試
//清除cookies res.clearCookie('islogin'); //清除session req.session.destroy();
寫在之后
最近比較忙,更新距上了篇時間較長了,本篇東西講的比較雜,講到的也比較有限,主要是為了后來會寫的一個示例打基礎;
本篇內容講到的一些知識點,其實都可以單獨拿一整篇去講,本篇基本原則是為了看了之后能使用;
要想弄清楚原理或者更多的相關知識,自已可以花點時間去了解,或者找點資料去豐富一下,當然也可以留言,在我覺得我沒亂說的情況下我會盡量解答^_^!