Nodejs學習筆記(六)--- Node.js + Express 構建網站預備知識

目錄

前言

  前面經過五篇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;
subform.js 代碼
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res) {
  res.render('usesession', { title: '使用session示例' });
});

module.exports = router;
usesession.js 代碼
var express = require('express');
var router = express.Router();

router.get('/', function(req, res) {
  res.render('usecookies', { title: '使用cookies示例' });
});

module.exports = router;
usecookies.js 代碼
var express = require('express');
var router = express.Router();

router.get('/', function(req, res) {
  res.render('usecrypto', { title: '加密字符串示例' });
});

module.exports = router;
usecrypto.js 代碼

  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怎麼做

  先來構建一個表單簡單模擬登錄GET方式提交數據

   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>
subform.ejs 示例代碼

  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;
subform.js get方式源碼

  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>
usesession.ejs 和 usecookies.ejs
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;
usession.js 示例代碼
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;
usecookies.js 示例代碼

  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();

寫在之後

  最近比較忙,更新距上了篇時間較長了,本篇東西講的比較雜,講到的也比較有限,主要是爲了後來會寫的一個示例打基礎;

 

  本篇內容講到的一些知識點,其實都可以單獨拿一整篇去講,本篇基本原則是爲了看了之後能使用;

 

  要想弄清楚原理或者更多的相關知識,自已可以花點時間去了解,或者找點資料去豐富一下,當然也可以留言,在我覺得我沒亂說的情況下我會盡量解答^_^!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章