理解Express中間件

閱讀目錄javascript

一:body-parser中間件html

二:cookie-parser中間件java

三:express-session 中間件node

四:理解使用morgan記錄操做日誌git

一:body-parser中間件github

body-parser是一個HTTP請求體解析的中間件,該中間件的做用是解析客戶端請求的body中的內容的,使用該模塊能夠解析JSON、Raw、文本、URL-encoded格式的請求體。web

如何使用?數據庫

在項目的根目錄下,執行命令,先下載 body-parser, 代碼執行以下:express

npm install body-parser --save

基本使用以下:npm

1. 首先須要引入進來: const bodyParser = require('body-parser');
2. 而後再進行解析,目前支持以下四種格式的解析,以下:

    1. 解析json數據:bodyParser.json(options)
    2. 解析二進制格式(好比Buffer數據流這樣的):bodyParser.raw(options);
    3. 解析文本數據: bodyParser.text(options);
    4. 解析UTF-8的編碼數據:bodyParser.urlencoded(options);

    bodyParser.json(options); 它返回一個僅解析json格式數據的中間件。該方法支持任意Unicode編碼的請求體,且支持gzip和deflate編碼的數據壓縮。

options參數有以下選項,及各選項的含義分別以下解析:

1)inflate: 該參數默認爲true,deflate壓縮數據被壓縮,設置爲false,壓縮數據會被拒絕。
2)limit: 設置請求的最大數據量,默認爲 '100kb'。
3)reviver: 傳遞給JSON.parse()方法的第二個參數。
4)strict: 默認爲true,僅會解析Array和Object兩種格式,若是設置爲false的話,就會解析全部的JSON.parse支持的格式。
5)type: 該選項用於設置爲指定MIME類型的數據使用當前解析的中間件。該選項能夠是一個函數或一個字符串,若是是字符串的話會
使用type-is來查找MIME類型;若是是函數的話,中間件會經過fn(req)來獲取實際值,默認爲 application/json.

bodyParser.raw(options); 它是返回一個將全部數據爲Buffer格式處理的中間件。其後全部的req.body中會是一個Buffer值。

options參數有以下選項,及各選項的含義分別以下解析:

1)inflate: 該參數默認爲true,deflate壓縮數據被壓縮,設置爲false,壓縮數據會被拒絕。
2)limit: 設置請求的最大數據量,默認爲 '100kb'。
3)type: 該選項用於設置爲指定MIME類型的數據使用當前解析的中間件。該選項能夠是一個函數或一個字符串,若是是字符串的話會
使用type-is來查找MIME類型;若是是函數的話,中間件會經過fn(req)來獲取實際值,默認爲 application/octet-stream.

bodyParser.text(options); 它是返回一個僅處理字符串格式處理的中間件。該req.body全部的將會是一個字符串值。

options參數有以下選項,及各選項的含義分別以下解析:

1)defaultCharset: 若是Content-Type沒有指定編碼的話,默認爲 'utf-8'.
2)inflate: 該參數默認爲true,deflate壓縮數據被壓縮,設置爲false,壓縮數據會被拒絕。
3)limit: 設置請求的最大數據量,默認爲 '100kb'。
4)type: 該選項用於設置爲指定MIME類型的數據使用當前解析的中間件。該選項能夠是一個函數或一個字符串,若是是字符串的話會
使用type-is來查找MIME類型;若是是函數的話,中間件會經過fn(req)來獲取實際值,默認爲 application/octet-stream.

bodyParser.urlencoded(options) 解析UTF-8編碼的數據,返回一個處理urlencoded數據的中間件。
options參數有以下選項,及各選項的含義分別以下解析:

1)extended - 當設置爲false時,會使用querystring庫解析URL編碼的數據;當設置爲true時,會使用qs庫解析URL編碼的數據。後沒有指定編碼時,使用此編碼。默認爲true。
2)inflate - 設置爲true時,deflate壓縮數據會被解壓縮;設置爲true時,deflate壓縮數據會被拒絕。默認爲true。
3)limit - 設置請求的最大數據量。默認爲'100kb'
4)parameterLimit - 用於設置URL編碼值的最大數據。默認爲1000
5)type - 該選項用於設置爲指定MIME類型的數據使用當前解析中間件。這個選項能夠是一個函數或是字符串,當是字符串是會使用type-is來查找MIMI類型;當爲函數是,中間件會經過fn(req)來獲取實際值。默認爲application/octet-stream。

如上bodyParser有四種方法來解析不一樣的數據,可是在實際項目中,咱們是如何使用的呢?
Express框架默認是使用body-parser做爲請求體解析中間件的。咱們能夠在項目中的根目錄下建立一個bodyParser.js代碼以下:
所以在運行執行,咱們還須要安裝express框架;安裝命令以下:

npm install --save express

bodyParser.js 代碼以下:

const express = require('express'); const bodyParser = require('body-parser'); const app = express(); // 對不一樣的路由使用不一樣的內容類型來解析

// 建立 application/json 解析
const jsonParser = bodyParser.json(); // 建立 application/x-www-form-urlencoded解析
const urlencodedParser = bodyParser.urlencoded({ extended: false }); // post /a 獲取URL編碼的請求體
app.post('/a', urlencodedParser, function(req, res) { if (!req.body) { return res.sendStatus(400); } console.log(req.body); res.send('welcome,' + req.body.userName); res.end(); }); // post /b 獲取URL編碼的請求體
app.post('/b', jsonParser, function(req, res) { if (!req.body) { return res.sendStatus(400); } res.send('welcome,' + req.body.userName); res.end(); }); const port = process.env.port || 3000; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

如上代碼,當咱們使用post請求 http://127.0.0.1:3000/a 請求的時候,他們使用的是 application/x-www-form-urlencoded格式來解析的,我這邊使用postman來演示下,以下所示:

當咱們使用 post請求 http://127.0.0.01:3000/b 的時候,咱們使用的是 application/json格式來解析的,那麼 Postman 以raw 方式發送JSON 數據,以下圖所示:

注意:若是在模擬器上以非JSON格式發送,則會得到一個空的JSON對象。

注意:若是咱們 app.use(bodyParser.urlencoded({ extended: false })) 這樣使用的話,那麼它會全局使用全部的都是以 application/x-www-form-urlencoded 來進行解析的。若是單個路由使用了 格式來解析的話,那麼使用的格式的優先級更高。

二:cookie-parser中間件

cookieParser中間件是用於獲取web瀏覽器發送的cookie中的內容。由於http協議它是無狀態的,用戶從A頁面跳轉到B頁面會發起http請求,當服務器端返回響應以後,當用戶A繼續訪問其餘頁面的時候,服務器端沒法獲知該狀態的,所以須要一個cookie來記錄用戶的狀態。

至於http無狀態的緣由,當初爲何須要這麼設計,官方文檔是以下說明的:

1. HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法,那個時候只有純粹靜態HTML頁面,所以不須要協議來保持狀態。

2. 用戶在收到響應的時候,通常會花一些時間來閱讀頁面,若是客戶端和服務器端還保持鏈接的話,那麼這個鏈接在大多數時候都將是空閒的,這是一種資源的浪費,所以HTTP最初的設計是短鏈接,即:客戶端和服務端完成一次請求和響應以後就斷開TCP鏈接,所以服務端沒法知道客戶端的下一個動做。

3. 這樣設計也可使HTTP協議更加的相對簡單,那麼這種簡單能夠賦予HTTP更強的擴展能力,所以好比session就是一種協議擴展。或者後來出現了CGI動態技術等。

而正是由於HTTP不能保持狀態的緣由,所以客戶端會出現cookie來保存狀態,及後面即將講解的session。所以瀏覽器第一次向服務器發送請求,服務器會返回一個cookie給客戶端瀏覽器,瀏覽器下一次發請求的時候,會把該cookie傳遞過去,所以服務器端就知道該cookie對應值,就能獲取該狀態的。

1) cookie是如何建立的?

express直接提供了對應的API,只要在響應中設置cookie便可,以下代碼所示:

function(req, res, next) { res.cookie(name, value, [, options]); }

如上代碼,express會將其填入 Response Header中的Set-Cookie中,達到瀏覽器中設置cookie的做用的。

如上參數 options 類型爲一個對象,可使用的屬性有以下:

domain: cookie在什麼域名下有效,類型爲String, 默認爲網站的域名。
expires: cookie的過時時間,類型爲Date, 若是沒有設置或設置爲0,那麼該cookie只在這個會話中有校,關閉瀏覽器的話,那麼cookie就會被瀏覽器刪除。
httpOnly: 只能被web server訪問。類型爲布爾型(Boolean)
maxAge: 實現expires的功能,設置cookie的過時時間,類型爲String,指明從如今開始,過多少毫秒之後,cookie到期。
path: cookie在什麼路徑下有校,默認爲 '/'
secure:  只能被HTTPS使用,默認爲false。
signed: 使用簽名,默認爲false。

通常簡單的用法以下:

res.cookie('name', 'kongzhi', { domain: 'xxx.abc.com', path: '/', secure: true }); //cookie的有效期爲900000ms
res.cookie('age', '30', { expires: new Date(Date.now() + 900000), httpOnly: true }); //cookie的有效期爲900000ms
res.cookie('age', '30', { maxAge: 900000, httpOnly: true }); //cookie的value爲對象
res.cookie('kongzhi1', { items: [1,2,3] }); res.cookie('kongzhi2', { items: [1,2,3] }, { maxAge: 900000 }); res.cookie('name', 'longen', { signed: true });

2)cookie是如何被刪除的?
express也提供了api刪除瀏覽器中的cookie,只須要調用對應的API便可,以下代碼:

function(req, res, next) { res.clearCookie(name, [, options]); }

3) cookie-parser 讀取cookie
在使用 cookie-parser 插件以前,咱們首先要安裝該插件,運行命令以下:

npm install --save cookie-parser

使用的demo基本以下(在項目的根目錄下新建 cookieParser.js, 代碼以下):

//引入cookieparser 框架,讀取客戶端發送的cookie
const express = require('express'); const cookieParase = require('cookie-parser'); var app = express(); //若是沒有,下面的req.cookies 會返回undefined
app.use(cookieParase()); app.use('/', function (req,res) { res.cookie('user', 'kongzhi'); console.log(req.cookies); res.send('cookie我來了'); }); const port = process.env.port || 3001; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

使用瀏覽器訪問 http://127.0.0.1:3001/ 而後再看下控制檯,能夠看到以下讀取到了:

下面咱們再來看個demo來理解使用cookie,首先須要有一個提交cookie的頁面 cookie.html, 該頁面顯示一個 '提交cookie' 按鈕,在用戶點擊該按鈕後,客戶端會建立一些cookie,而後使用 XMLHttpRequest對象向服務器端提交數據,該頁面全部的cookie也會被提交上去,待接到服務器端響應數據後會將這些數據顯示在頁面中。

在項目的根目錄中新建 cookie.html 代碼以下:

<!DOCTYPE html> 
<html>
<head>
  <title>cookie</title>
  <meta charset="utf-8">
  <style> #result { font-size: 16px;
    }
  </style>
</head>
<body>
  <div id="app">
    <form id="form1" method="post" action='index.html'>
      <input type="button" value="提交cookie" onclick="cookieTest()" />
    </form>
    <div id="result"></div>
  </div>
  <script type="text/javascript">
    function cookieTest() { var xhr = new XMLHttpRequest(); xhr.open('post', 'cookie.html', true); document.cookie = 'username=kongzhi'; document.cookie = 'age=30'; xhr.onload = function() { if (this.status === 200) { document.getElementById('result').innerHTML = this.response; } }; xhr.send(); } </script>
</body>
</html>

在項目中的根目錄新建 testCookie.js 代碼以下:

const express = require('express'); const cookieParase = require('cookie-parser'); const fs = require('fs'); const app = express(); app.use(cookieParase()); app.get('/cookie.html', function(req, res) { res.sendfile(__dirname + '/cookie.html'); }); app.post('/cookie.html', function(req, res) { for (const key in req.cookies) { res.write('cookie名:' +key); res.write(',cookie值爲:'+req.cookies[key] + "<br/>"); } res.end(); }); const port = process.env.port || 3002; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

而後咱們進入項目中的根目錄運行 node testCookie.js ,接着瀏覽器訪問 http://127.0.0.1:3002/cookie.html 後點擊提交,
能夠看到以下顯示了。以下所示:

三:express-session 中間件

session中間件用於保存用戶數據提供一個session管理器,它和cookie相似,都是記錄用戶狀態的,而與cookie不一樣的是:
cookie有以下限制:
1. cookie存儲的大小最多爲4kb。
2. cookie有域或路徑的概念,而且最重要的一點是 cookie安全性很低,通常重要的信息,好比用戶名和密碼這樣的不容許放入cookie裏面的。

如上cookie有最主要上面兩點的缺點,所以對於安全性的一些信息建議放到session上存儲,session是保存到服務器上的。

session基本原理:當客戶端向服務端請求時,會建立一個session標識(好比叫jsessionid)存在客戶端的cookie當中,每次請求的時候服務器端首先會檢查這個客戶端的請求裏面是否已經包含了一個session標識,若是已經包含了,那麼服務器端就會根據該session標識把對應的數據檢索出來,若是不包含的話,服務端會建立一個新的session標識傳給客戶端cookie中,之後客戶端每次請求的時候,從cookie中獲取該標識把它傳遞過來。

服務端執行session機制的時候會生成Session口令,在Tomcat默認會採用jsessionid這個值,可是在其餘服務器上會有所不一樣,好比Connect默認會叫 connect_uid, 雖然把一些敏感信息放到cookie當中是不可取的,可是將口令放在cookie中仍是能夠的,若是口令被篡改了的話,就丟失了映射關係,也沒法修改服務端存在的數據了,而且session的有效期是很是短的,通常爲20分鐘,若是在20分鐘內客戶端和服務器端沒有產生交互,服務端會將數據刪除掉。

express-session 是服務器端保存數據的中間件,安裝命令以下所示:

npm install express-session --save

而後在js中引入後,再接着use便可,簡單的代碼以下:

const express = require('express'); const app = express(); const session = require('express-session'); app.use(session(options));

如上參數 options 值爲一個對象,它有以下屬性值:

key: String類型,用於指定用來保存session的cookie名稱,默認爲 connect.sid.
store: 屬性值爲一個用來保存session數據的第三方存儲對象。
fingerprint: 屬性值爲一個自定義指紋生成的函數。
cookie: 屬性值爲一個用來指定保存session數據的cookie設置的對象,默認值爲 {path: '/', httpOnly: true, maxAge: 14400000}, path是用於指定cookie保存的路徑,httpOnly屬性值用於指定是否只針對http保存的cookie,maxAge用於指定cookie的過時時間,單位爲毫秒。

secret: 屬性值爲一個字符串,用來指定來對session數據進行加密的字符串。

下面咱們來和cookie同樣,作一個簡單的demo,來理解下使用 session的實列。

在頁面中index.html 有一個form表單post提交數據,頁面一訪問的時候,監聽get請求,給session設置數據,好比用戶名和密碼這樣的,而後當我按鈕提交post請求的時候,咱們在服務器端監聽post請求,而後把剛剛保存的session數據打印出來,代碼以下:

session.html 代碼以下:

<!DOCTYPE html> 
<html>
<head>
  <title>cookie</title>
  <meta charset="utf-8">
  <style> #result { font-size: 16px;
    }
  </style>
</head>
<body>
  <div id="app">
    <form id="form1" method="post" action='session.html'>
      <input type="submit" />
    </form>
    <div id="result"></div>
  </div>
</body>
</html>

session.js 代碼以下:

const express = require('express'); const fs = require('fs'); const app = express(); const cookieParase = require('cookie-parser'); const sessionParser = require('express-session'); app.use(cookieParase()); app.use(sessionParser({secret: 'test'})); app.get('/session.html', function(req, res) { res.sendfile(__dirname+'/session.html'); req.session.username = 'kongzhi111'; req.session.password = '123456'; }); app.post('/session.html', function(req, res) { console.log(req.session.username); console.log(req.session.password); res.end(); }); const port = process.env.port || 3003; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

在命令行中,執行命令 node session.js, 而後在瀏覽器中 訪問 http://127.0.0.1:3003/session.html ,點擊按鈕後,在命令行中打印以下信息,以下所示:

1)理解使用 http.IncomingMessage 中regenerate 方法從新生成一個session管理器

咱們也可使用 http.IncomingMessage對象的session屬性值對象的 regenerate 方法從新生成一個session管理器,以下基本代碼:

req.session.regenerate(function(err) {});

session.js 代碼改爲以下:

const express = require('express'); const fs = require('fs'); const app = express(); const cookieParase = require('cookie-parser'); const sessionParser = require('express-session'); app.use(cookieParase()); app.use(sessionParser({secret: 'test'})); app.get('/session.html', function(req, res) { res.sendfile(__dirname+'/session.html'); req.session.username = 'kongzhi111'; req.session.password = '123456'; req.session.regenerate(function(err) { if (err) { console.log('session從新初始化失敗'); } else { console.log('session被從新初始化'); } }); }); app.post('/session.html', function(req, res) { console.log(req.session.username); console.log(req.session.password); res.end(); }); const port = process.env.port || 3003; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

在頁面瀏覽器訪問 http://127.0.0.1:3003/session.html 後,命令行中會打印 以下所示:

而後點擊提交後,命令中打印以下:

2)理解使用 http.IncomingMessage 中的destroy方法銷燬當前在用的session管理器

destroy使用方式以下:

req.session.destroy(function(err) {});

session.js 代碼改爲以下:

const express = require('express'); const fs = require('fs'); const app = express(); const cookieParase = require('cookie-parser'); const sessionParser = require('express-session'); app.use(cookieParase()); app.use(sessionParser({secret: 'test'})); app.get('/session.html', function(req, res) { res.sendfile(__dirname+'/session.html'); req.session.username = 'kongzhi111'; req.session.password = '123456'; req.session.destroy(function(err) { if (err) { console.log('session銷燬失敗'); } else { console.log('session被銷燬'); } }); }); app.post('/session.html', function(req, res) { console.log(req.session.username); console.log(req.session.password); res.end(); }); const port = process.env.port || 3003; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

同理在瀏覽器中運行 http://127.0.0.1:3003/session.html 後,在命令行中看到以下信息:

而後當咱們點擊按鈕後,在命令行中看到以下信息:

3)查看http.IncomingMessage對象的session中保存cookie屬性的全部信息

session代碼以下:

const express = require('express'); const fs = require('fs'); const app = express(); const cookieParase = require('cookie-parser'); const sessionParser = require('express-session'); app.use(cookieParase()); app.use(sessionParser({secret: 'test', cookie: {maxAge: 3600000}})); app.get('/session.html', function(req, res) { res.sendfile(__dirname+'/session.html'); console.log(req.session.cookie); }); const port = process.env.port || 3003; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

查看效果以下:

4)使用http.IncomingMessage對象session對象獲取cookie的剩餘時間

session.js 代碼以下:

const express = require('express'); const fs = require('fs'); const app = express(); const cookieParase = require('cookie-parser'); const sessionParser = require('express-session'); app.use(cookieParase()); app.use(sessionParser({secret: 'test', cookie: {maxAge: 3600000}})); app.get('/session.html', function(req, res) { res.sendfile(__dirname+'/session.html'); var h = 3600000; req.session.cookie.expires = new Date(Date.now() + h); req.session.cookie.maxAge = h; setTimeout(function() { console.log('cookie的剩餘時間'+req.session.cookie.maxAge); }, 5000); }); const port = process.env.port || 3003; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

打印以下所示:

咱們最後再來看下瀏覽器請求頭信息,以下:

請求頭看到 服務器會返回 cookie 和 用於指定用來保存session的cookie名稱,默認爲 connect.sid, connect.sid 是session的簽名,做用是知道session是否被修改過。

5)使用Express + session 實現用戶登陸

當咱們登陸淘寶網站的時候,登陸成功後,咱們沒有點擊退出按鈕或有效期沒有過時的狀況下,咱們把瀏覽器關閉掉,從新進入淘寶的首頁會發現咱們的session會話還一直保持登陸狀態,那麼這個狀態就是session幫咱們保存下來的。那麼它在node中是如何實現的呢?

用戶登陸的基本原理是:若是用戶沒有登陸或者登陸時用戶名或密碼錯誤的時候,那麼服務器將該請求重定向到登陸頁,或者的話就登陸成功,登陸成功後,服務器須要記錄保存該客戶端的登陸狀態,那麼下一次服務器請求主頁的時候,會先判斷客戶端的登陸狀態,若是登陸狀態在
有效期內是有效的,就直接進入主頁,不然的話,和以前同樣會重定向到登陸頁面。

下面如何使用session來作這件事的呢?

下面咱們須要以下目錄結構

|-- demo1 # 項目根目錄 | |--- login.html # 登陸頁面 | |--- home.html # 主頁 | |--- app.js       # node服務端

至於 package.json 和項目是同目錄的。下面先看下 login.html 代碼以下:

<!DOCTYPE html> 
<html>
<head>
  <title>expree+session實現用戶登陸</title>
  <meta charset="utf-8">
</head>
<body>
  <div id="app">
    <form action="/login" method="post">
      <p>
        <label>用戶名:</label>
        <input type="text" name="username" />
      </p>
      <p>
        <label>密碼:</label>
        <input type="password" name="password" />
      </p>
      <input type="submit" value="提交" />
    </form>
  </div>
</body>
</html>

home.html 代碼以下:

<!DOCTYPE html> 
<html>
<head>
  <title>expree+session實現用戶登陸</title>
  <meta charset="utf-8">
</head>
<body>
  <div id="app">
    <div> 用戶名:<span><%= username %></span>
      <a href="/logout">退出登陸</a>
    </div>
  </div>
</body>
</html>

如上home.html 代碼,使用了 <%= username %> 這樣的語法,這個是ejs模板語法,所以咱們須要安裝一下 ejs 以下命令安裝:

npm install ejs --save

下面咱們再來看看服務器端 app.js 代碼如何處理業務的,代碼以下:

const express = require('express'); const app = express(); const session = require('express-session'); const bodyParser = require('body-parser'); const ejs = require('ejs').__express; app.set('views', __dirname); // 設置模板目錄
app.set('view engine', 'html'); // 設置模板引擎爲 html
app.engine('html', ejs); // 使用ejs模板引擎解析html文件中ejs語法
 app.use(bodyParser.json()); // 使用 body-parser中間件 json形式

// 解析UTF-8編碼的數據,返回一個處理urlencoded數據的中間件
app.use(bodyParser.urlencoded({ extended: true })); // 使用session中間件 設置cookie相關的信息
 app.use(session({ secret: 'test', // 對 session id 相關的cookie 進行加密簽名
 cookie: { maxAge: 1000 * 60 * 1  // 設置 session的有效時間,單位爲毫秒,設置有效期爲1分鐘
 } })); // get 登陸頁面
app.get('/login', (req, res) => { res.sendFile(__dirname + '/login.html'); }); // 監聽post表單事件 用戶登陸
app.post('/login', (req, res) => { // 這裏沒有鏈接數據庫,因此用戶名和密碼假如是寫死的,因此簡單進行判斷一下
  if (req.body.username === 'kongzhi' && req.body.password === '123456') { req.session.username = req.body.username; // 登陸成功,把登陸信息保存到session裏面去了
    // 登陸成功後,進行重定向到首頁
    res.redirect('/'); } else { // 用戶名或密碼登陸錯誤
 res.json({ 'code': 1, 'errorMsg': '帳戶或密碼錯誤' }); } }); // 處理重定向首頁的邏輯代碼
app.get('/', (req, res) => { // 若是session有已經登陸的用戶名的話,且有效期有效的話,則到 home.html, 不然重定向到登陸頁面
  if (req.session.username) { res.render('home', {username: req.session.username}); } else { res.redirect('login'); } }); // 處理退出的邏輯
app.get('/logout', (req, res) => { req.session.username = null; // 刪除session
  // 重定向到登陸頁面
  res.redirect('login'); }); const port = process.env.port || 3004; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

首先在命令行中 執行 node app.js ,而後在瀏覽器中訪問 http://127.0.0.1:3004 後,以下所示:

當我輸入正確的用戶名和密碼成功後,以下圖所示:

session的有效期是1分鐘,在1分鐘以內無論如何刷新頁面,都是在home.html頁面,1分鐘以後,session過時了,再刷新頁面會自動跳轉到登陸頁面去了。這時候就須要從新登陸了。固然在home頁面,你能夠點擊退出按鈕,退出到登陸頁面去。

四:理解使用morgan記錄操做日誌

morgan中間件是來記錄詳細的操做日誌或錯誤日誌的。

1)morgan 安裝命令以下所示:

npm install --save morgan

2) 基本使用方式以下:

const express = require('express'); const app = express(); const morgan = require('morgan'); app.use(morgan(format, [, options]));

如上代碼使用morgan, morgan(format, options);

參數 format(可選)該參數定義了幾種日誌格式,每種格式都有對應的名稱,默認是default,詳細有哪些格式,請看github官網(https://github.com/expressjs/morgan/#predefined-formats)

參數 options(可選),包含 stream, skip, immediate
stream: 日誌輸出流配置,默認是 process.stdout
skip: 是否跳過日誌記錄,使用方式看github上(https://github.com/expressjs/morgan/#skip)
immediate: 布爾值,默認false,含義是在請求返回後,再記錄日誌,若是爲true的話,含義是一收到請求,就記錄日誌。

1)下面咱們來看下簡單的demo來理解下morgan的使用:

基本結構目錄以下:

---morgan #項目的文件夾 |--- morgan.html # html文件 |--- morgan.js     # js文件

morgan.html 代碼以下:

<!DOCTYPE html> 
<html>
<head>
  <title>morgan</title>
  <meta charset="utf-8">
</head>
<body>
  <div id="app">
    <form id="form1">
      <input type="text" id="username" />
      <input type="button" value='提交' onclick="clickFunc()"/>
    </form>
    <div id="result"></div>
  </div>
  <script type="text/javascript">
    function clickFunc() { var obj = { username: document.getElementById('username').value }; var xhr = new XMLHttpRequest(); xhr.open('POST', 'morgan.html', true); xhr.onload = function(e) { if (this.status === 200) { document.getElementById('result').innerHTML = this.response; } }; xhr.send(JSON.stringify(obj)); } </script>
</body>
</html>

morgan.js 代碼以下:

const express = require('express'); const morgan = require('morgan'); const app = express(); // 使用中間件,'combined' 是日誌顯示的格式,具體看github上(https://github.com/expressjs/morgan/#predefined-formats)
app.use(morgan('combined')); app.get('/morgan.html', (req, res) => { res.sendFile(__dirname + '/morgan.html'); }); // post 請求監聽 
app.post('/morgan.html', (req, res) => { req.on('data', (data) => { console.log(data.toString()); res.end(); }); }); const port = process.env.port || 3005; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

當咱們在項目的對應目錄下 執行 node morgan.js 會啓動服務器,而後在瀏覽器中 http://127.0.0.1:3005/morgan.html中訪問的時候,會打印出以下信息:

當咱們輸入內容後,點擊提交,會打印以下日誌信息,以下所示:

2)如何將日誌信息保存到文件內?
morgan提供了寫入文件流將這些日誌相關的信息保存到文件中,以下morgan.js代碼改爲以下:

const express = require('express'); const morgan = require('morgan'); const app = express(); const fs = require('fs'); const path = require('path'); const accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log')); // 使用中間件,'combined' 是日誌顯示的格式,具體看github上(https://github.com/expressjs/morgan/#predefined-formats)
app.use(morgan('combined', {stream: accessLogStream})); app.get('/morgan.html', (req, res) => { res.sendFile(__dirname + '/morgan.html'); }); // post 請求監聽 
app.post('/morgan.html', (req, res) => { req.on('data', (data) => { console.log(data.toString()); res.end(); }); }); const port = process.env.port || 3005; app.listen(port, () => { console.log('http://127.0.0.1:%s', port) });

如上代碼,把日誌信息寫入文件中 在morgan.js 同級目錄下會自動生成 access.log 日誌文件。

上面全部的demo,能夠到github上查看

相關文章
相關標籤/搜索