深刻理解nodejs中Express的中間件

Express是一個基於Node.js平臺的web應用開發框架,在Node.js基礎之上擴展了web應用開發所須要的基礎功能,從而使得咱們開發Web應用更加方便、更加快捷。html

舉一個例子:node

用node.js實現一個控制檯打印「hello server」web

?
1
2
3
4
5
var http = require( 'http' );
var server = http.createServer( function (req,res){
  console.log( "hello server" );
});
server.listen(3000);

這樣子的話,當咱們須要處理各類請求(主要指GET、POST)時,咱們須要將全部請求類型處理的代碼寫在createServer包裹的函數裏。數據庫

用Express實現一個控制檯打印「hello server」express

?
1
2
3
4
5
6
7
8
var express = require( 'express' );
var app = express();
http.createServer(app);
  
// 處理用戶請求(路由)
app.get( "/" , function (){
  console.log( "hello server" );
})

Express處理各類請求是經過Express執行函數去調用對應的方法,這樣是否是更加方便和快捷了。瀏覽器

Express的API文檔完整易懂,2010-01-03陸續發佈了幾個版本,其中第三版和第四版差別比較大, 主要體如今第三版的中間件基本上都是繼承了connect框架的,而第四版將中間件獨立出來了,不在依賴connect框架。服務器

說到中間件,官網對它的闡述是這樣的:cookie

「Express是一個自身功能極簡,徹底是路由和中間件構成一個web開發框架:從本質上來講,一個Express應用就是在調用各類中間件。」session

因而可知,中間件在Express開發中的重要性,所以這裏咱們就專門來總結一下中間件。app

1、中間件結構

一、app.use([path],function)

path:是路由的url,默認參數‘/',意義是路由到這個路徑時使用這個中間件

function:中間件函數

這個中間件函數能夠理解爲就是function(request,response,next)

這裏安裝是指涉及到第三方中間件的使用時,須要先安裝好,而後在使用。

2、中間件分類

一、內置中間件

 express.static 是Express目前惟一內置的一箇中間件。用來處理靜態資源文件。

什麼意思了? 來run一下代碼看看

?
1
2
3
4
5
// index.js
var express = require( 'express' );
var app = express();
  
app.use(express.static(__dirname +  '/public' ));

啓動服務: node index.js

瀏覽器中訪問: http://localhost:1234/ 展現的/public/index.html內容

瀏覽器中訪問: http://localhost:1234/hello.html 展現的/public/hello.html內容

二、自定義中間件

在上面中間件結構中,咱們知道了,中間件使用時的第二個參數是一個Function,然而,要自定義一箇中間件,就是倒騰一番這個Function。

這個function總共有三個參數(req,res,next);

當每一個請求到達服務器時,nodejs會爲請求建立一個請求對象(request),該請求對象包含客戶端提交上來的數據。同時也會建立一個響應對象(response),響應對象主要負責將服務器的數據響應到客戶端。而最後一個參數next是一個方法,由於一個應用中可使用多箇中間件,而要想運行下一個中間件,那麼上一個中間件必須運行next()。

好了,有了一個大概的瞭解,下面我定義一些中間件來實現一個路由功能。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var express = require( 'express' );
var app = express();
  
app.use( function (request,response,next){
  if (request.url ===  '/' ){
   response.writeHead(200,{ "Content-Type" : "text/plain" });
   response.end( "This is home\n" );
  else {
   next();
  }
})
app.use( function (request,response,next){
  if (request.url ===  '/about' ){
   response.writeHead(200,{ "Content-Type" : "text/plain" });
   response.end( "This is about\n" );
  else {
   next();
  }
})
app.use( function (request,response,next){
  response.writeHead(404,{ "Content-Type" : "text/plain" });
  response.end( "404 not found!\n" );
})
app.listen(1234, 'localhost' );

瀏覽器中訪問: http://localhost:1234/ 展現This is home

瀏覽器中訪問: http://localhost:1234/about 展現This is about

這樣看是否是使用中間件很輕鬆就實現了路由的功能,固然,有關Express的路由能夠專門拿出來寫寫,哈哈。

三、第三方中間件

有關第三方中間件,這裏咱們分析幾個比較重要和經常使用的,知道這幾個的使用,其它的也就會了。

body-parser :解析body中的數據,並將其保存爲Request對象的body屬性。

cookie-parser :解析客戶端cookie中的數據,並將其保存爲Request對象的cookie屬性

express-session :解析服務端生成的sessionid對應的session數據,並將其保存爲Request對象的session屬性

query:這個中間件將一個查詢字符串從URL轉換爲JS對象,並將其保存爲Request對象的query屬性。這個中間件在第四個版本中已經內置了無需安裝。

下面來一個例子,功能是:用戶能否登陸和在服務端保存登陸態。

?
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
var express = require( 'express' );
// 引入模板引擎
var hbs = require( 'express-handlebars' );
var bodyParser = require( 'body-parser' );
var session = require( 'express-session' );
  
var app = express();
  
// hbs是一個模板引擎
app.engine( 'hbs' ,hbs());
app.set( 'view engine' , 'hbs' );
app.set( 'views' , 'templates' );
  
// 數據庫讀出來的數據
var userArr = [ 'wpzheng' ];
  
app.use(session({secret: 'maizidu' }));
app.use(bodyParser.urlencoded({extended: true }));
  
app.get( '/' function (request,response,next){
  var username = request.session.username;
  if (username){
   response.send( "hello" + username);
  } else {
   response.render( 'form' );
  }
});
  
app.post( '/' function (request,response){
   if (userArr.indexOf(request.body.username)>=0){
    request.session.username = request.body.username;
   } else {
    request.session.destroy();
   }
     // response對象的一個方法 重定向做用
   response.redirect( '/' );
});
app.listen(1234, 'localhost' );

若是session沒有保存數據(測試時能夠將服務關閉,session就沒有值了,每次向服務器發送請求時,服務會建立一個新的session),就會自動跳到登陸頁面。當已登陸過(也就是說有session值),就直接顯示username。

這個例子涉及到模板(hbs)和response的方法(redirect)能夠先無論。

3、中間件理解

寫到最後了,回到最開始的問題,你是否理解了什麼是Express中間件?

結合上面講解時給出的例子,咱們先來分析一下從瀏覽器地址欄輸入url到客戶端顯示數據之間這個過程到底發生了什麼。

瀏覽器向服務器發送一個請求後,服務器直接經過request.定位屬性的方式獲得經過request攜帶過去的數據(有用戶輸入的數據和瀏覽器自己的數據信息)。這中間就必定有一個函數將這些數據分類作了處理,已經處理好了,最後讓request對象調用使用,對的,這個處理數據處理函數就是咱們要說的 中間件 。因而可知,中間件能夠總結如下幾點:

一、封裝了一些處理一個完整事件的功能函數。

二、非內置的中間件須要經過安裝後,require到文件就能夠運行。

三、封裝了一些或許複雜但確定是通用的功能。

Express是一個基於Node.js平臺的web應用開發框架,在Node.js基礎之上擴展了web應用開發所須要的基礎功能,從而使得咱們開發Web應用更加方便、更加快捷。

舉一個例子:

用node.js實現一個控制檯打印「hello server」

?
1
2
3
4
5
var http = require( 'http' );
var server = http.createServer( function (req,res){
  console.log( "hello server" );
});
server.listen(3000);

這樣子的話,當咱們須要處理各類請求(主要指GET、POST)時,咱們須要將全部請求類型處理的代碼寫在createServer包裹的函數裏。

用Express實現一個控制檯打印「hello server」

?
1
2
3
4
5
6
7
8
var express = require( 'express' );
var app = express();
http.createServer(app);
  
// 處理用戶請求(路由)
app.get( "/" , function (){
  console.log( "hello server" );
})

Express處理各類請求是經過Express執行函數去調用對應的方法,這樣是否是更加方便和快捷了。

Express的API文檔完整易懂,2010-01-03陸續發佈了幾個版本,其中第三版和第四版差別比較大, 主要體如今第三版的中間件基本上都是繼承了connect框架的,而第四版將中間件獨立出來了,不在依賴connect框架。

說到中間件,官網對它的闡述是這樣的:

「Express是一個自身功能極簡,徹底是路由和中間件構成一個web開發框架:從本質上來講,一個Express應用就是在調用各類中間件。」

因而可知,中間件在Express開發中的重要性,所以這裏咱們就專門來總結一下中間件。

1、中間件結構

一、app.use([path],function)

path:是路由的url,默認參數‘/',意義是路由到這個路徑時使用這個中間件

function:中間件函數

這個中間件函數能夠理解爲就是function(request,response,next)

這裏安裝是指涉及到第三方中間件的使用時,須要先安裝好,而後在使用。

2、中間件分類

一、內置中間件

 express.static 是Express目前惟一內置的一箇中間件。用來處理靜態資源文件。

什麼意思了? 來run一下代碼看看

?
1
2
3
4
5
// index.js
var express = require( 'express' );
var app = express();
  
app.use(express.static(__dirname +  '/public' ));

啓動服務: node index.js

瀏覽器中訪問: http://localhost:1234/ 展現的/public/index.html內容

瀏覽器中訪問: http://localhost:1234/hello.html 展現的/public/hello.html內容

二、自定義中間件

在上面中間件結構中,咱們知道了,中間件使用時的第二個參數是一個Function,然而,要自定義一箇中間件,就是倒騰一番這個Function。

這個function總共有三個參數(req,res,next);

當每一個請求到達服務器時,nodejs會爲請求建立一個請求對象(request),該請求對象包含客戶端提交上來的數據。同時也會建立一個響應對象(response),響應對象主要負責將服務器的數據響應到客戶端。而最後一個參數next是一個方法,由於一個應用中可使用多箇中間件,而要想運行下一個中間件,那麼上一個中間件必須運行next()。

好了,有了一個大概的瞭解,下面我定義一些中間件來實現一個路由功能。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var express = require( 'express' );
var app = express();
  
app.use( function (request,response,next){
  if (request.url ===  '/' ){
   response.writeHead(200,{ "Content-Type" : "text/plain" });
   response.end( "This is home\n" );
  else {
   next();
  }
})
app.use( function (request,response,next){
  if (request.url ===  '/about' ){
   response.writeHead(200,{ "Content-Type" : "text/plain" });
   response.end( "This is about\n" );
  else {
   next();
  }
})
app.use( function (request,response,next){
  response.writeHead(404,{ "Content-Type" : "text/plain" });
  response.end( "404 not found!\n" );
})
app.listen(1234, 'localhost' );

瀏覽器中訪問: http://localhost:1234/ 展現This is home

瀏覽器中訪問: http://localhost:1234/about 展現This is about

這樣看是否是使用中間件很輕鬆就實現了路由的功能,固然,有關Express的路由能夠專門拿出來寫寫,哈哈。

三、第三方中間件

有關第三方中間件,這裏咱們分析幾個比較重要和經常使用的,知道這幾個的使用,其它的也就會了。

body-parser :解析body中的數據,並將其保存爲Request對象的body屬性。

cookie-parser :解析客戶端cookie中的數據,並將其保存爲Request對象的cookie屬性

express-session :解析服務端生成的sessionid對應的session數據,並將其保存爲Request對象的session屬性

query:這個中間件將一個查詢字符串從URL轉換爲JS對象,並將其保存爲Request對象的query屬性。這個中間件在第四個版本中已經內置了無需安裝。

下面來一個例子,功能是:用戶能否登陸和在服務端保存登陸態。

?
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
var express = require( 'express' );
// 引入模板引擎
var hbs = require( 'express-handlebars' );
var bodyParser = require( 'body-parser' );
var session = require( 'express-session' );
  
var app = express();
  
// hbs是一個模板引擎
app.engine( 'hbs' ,hbs());
app.set( 'view engine' , 'hbs' );
app.set( 'views' , 'templates' );
  
// 數據庫讀出來的數據
var userArr = [ 'wpzheng' ];
  
app.use(session({secret: 'maizidu' }));
app.use(bodyParser.urlencoded({extended: true }));
  
app.get( '/' function (request,response,next){
  var username = request.session.username;
  if (username){
   response.send( "hello" + username);
  } else {
   response.render( 'form' );
  }
});
  
app.post( '/' function (request,response){
   if (userArr.indexOf(request.body.username)>=0){
    request.session.username = request.body.username;
   } else {
    request.session.destroy();
   }
     // response對象的一個方法 重定向做用
   response.redirect( '/' );
});
app.listen(1234, 'localhost' );

若是session沒有保存數據(測試時能夠將服務關閉,session就沒有值了,每次向服務器發送請求時,服務會建立一個新的session),就會自動跳到登陸頁面。當已登陸過(也就是說有session值),就直接顯示username。

這個例子涉及到模板(hbs)和response的方法(redirect)能夠先無論。

3、中間件理解

寫到最後了,回到最開始的問題,你是否理解了什麼是Express中間件?

結合上面講解時給出的例子,咱們先來分析一下從瀏覽器地址欄輸入url到客戶端顯示數據之間這個過程到底發生了什麼。

瀏覽器向服務器發送一個請求後,服務器直接經過request.定位屬性的方式獲得經過request攜帶過去的數據(有用戶輸入的數據和瀏覽器自己的數據信息)。這中間就必定有一個函數將這些數據分類作了處理,已經處理好了,最後讓request對象調用使用,對的,這個處理數據處理函數就是咱們要說的 中間件 。因而可知,中間件能夠總結如下幾點:

一、封裝了一些處理一個完整事件的功能函數。

二、非內置的中間件須要經過安裝後,require到文件就能夠運行。

三、封裝了一些或許複雜但確定是通用的功能。

相關文章
相關標籤/搜索