Like Share Discussion Bookmark Smile

J.J. Huang   2020-02-08   Node.js   瀏覽次數:

Node.js | Express 框架(上)

簡介

Express是一個簡潔而靈活的node.js Web應用框架,提供了一系列強大特性幫助你建立各種Web應用,和豐富的HTTP工具。

使用Express可以快速地搭建一個完整功能的網站。

Express框架核心特性:

  • 可以設置中間件來響應HTTP請求。
  • 定義了路由表用於執行不同的HTTP請求動作。
  • 可以通過向模板傳遞參數來動態渲染HTML頁面。

安裝 Express

1
npm install express --save

Express框架安裝在當前目錄的node_modules目錄中,node_modules目錄下會自動建立express目錄。

以下幾個重要的模組是需要與express框架一起安裝的:

  • body-parsernode.js中間件,用於處理JSONRawTextURL編碼的資料。
  • cookie-parser:這就是一個解析Cookie的工具。通過req.cookies可以取到傳過來的cookie,並把它們轉成對象。
  • multernode.js中間件,用於處理enctype="multipart/form-data"(設置表單的MIME編碼)的表單資料。

註:如在install過程中有錯誤,可以參考NPM 使用介绍 - 錯誤處理

查看下express使用的版本號:

1
2
3
$ npm list express
express_demo@1.0.0 /Users/morose/Documents/Temp/Example/Express_demo
└── express@4.17.1

Express 框架範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// express_demo.js 文件
var express = require('express');
var app = express();
 
app.get('/', function (req, res) {
   res.send('Hello World');
})
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("瀏覽地址為 http://%s:%s", host, port)
 
})

執行結果如下:

1
2
$ node express_demo.js
瀏覽地址為 http://:::8081

為什麼是::

根據express官方文件對app.listen()函數的文件說明,它完全等同於Node.jsserver.listen()

該函數的官方文件中對參數host描述如下:

1
2
3
4
5
If port is omitted or is 0, the operating system will assign an arbitrary unused port, which can be retrieved by using server.address().port after the 'listening' event has been emitted.

If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.

In most operating systems, listening to the unspecified IPv6 address (::) may cause the net.Server to also listen on the unspecified IPv4 address (0.0.0.0).

翻譯:

1
2
3
4
5
如果port被省略或為0,操作系統會自動分配一個任意的未被使用的端口號;你可以在'listening'事件被觸發後,通過使用 server.address().port 來獲取到該端口號。

當參數host被省略時,如果服務器的IPv6地址是可用的,那麼服務器將使用本機所有的IPv6地址(::)來接受連接;否則,將使用本機所有的IPv4地址(0.0.0.0)來接受連接。

在大多數操作系統上,監聽本機所有的IPv6地址(::)可能導致net.Server 也監聽本機所有的IPv4地址(0.0.0.0)。

根據文件描述,如果你明確地只想使用(監聽)IPv4地址。
那麼你可以將最後一行程式碼改為:

1
app.listen(3000, '0.0.0.0');

修改後

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// express_demo.js 文件
var express = require('express');
var app = express();
 
app.get('/', function (req, res) {
   res.send('Hello World');
})
 
var server = app.listen(8081, '0.0.0.0', function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("瀏覽地址為 http://%s:%s", host, port)
 
})

執行結果如下:

1
2
$ node express_demo.js
瀏覽地址為 http://0.0.0.0:8081

開啟瀏覽器瀏覽:

1
http://0.0.0.0:8081

請求和響應

Express應用使用回調函數的參數:requestresponse對象來處理請求和響應的資料。

1
2
3
app.get('/', function (req, res) {
   // --
})

requestresponse對象的具體介紹:

  • Request對象:request對象表示HTTP請求,包含了請求查詢字符串,參數,內容,HTTP頭部等屬性。常見屬性有:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
req.app:當callback為外部文件時,用req.app訪問express的範例
req.baseUrl:獲取路由當前安裝的URL路徑
req.body / req.cookies:獲得「請求主體」/ Cookies
req.fresh / req.stale:判斷請求是否還「新鮮」
req.hostname / req.ip:獲取主機名和IP地址
req.originalUrl:獲取原始請求URL
req.params:獲取路由的parameters
req.path:獲取請求路徑
req.protocol:獲取協議類型
req.query:獲取URL的查詢參數串
req.route:獲取當前匹配的路由
req.subdomains:獲取子域名
req.accepts():檢查可接受的請求的文件類型
req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一個可接受字符編碼
req.get():獲取指定的HTTP請求頭
req.is():判斷請求頭Content-Type的MIME類型

註:Express request documentation

  • Response對象:response對象表示HTTP響應,即在接收到請求時向客戶端發送的HTTP響應資料。常見屬性有:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
res.app:同req.app一樣
res.append():追加指定HTTP頭
res.set()在res.append()後將重置之前設置的頭
res.cookie(name,value [,option]):設置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
res.clearCookie():清除Cookie
res.download():傳送指定路徑的文件
res.get():返回指定的HTTP頭
res.json():傳送JSON響應
res.jsonp():傳送JSONP響應
res.location():只設置響應的Location HTTP頭,不設置狀態碼或者close response
res.redirect():設置響應的Location HTTP頭,並且設置狀態碼302
res.render(view,[locals],callback):渲染一個view,同時向callback傳遞渲染後的字符串,如果在渲染過程中有錯誤發生next(err)將會被自動調用。 callback將會被傳入一個可能發生的錯誤以及渲染後的頁面,這樣就不會自動輸出了。
res.send():傳送HTTP響應
res.sendFile(path \[,options] \[,fn\]):傳送指定路徑的文件 -會自動根據文件extension設定Content-Type
res.set():設置HTTP頭,傳入object可以一次設置多個頭
res.status():設置HTTP狀態碼
res.type():設置Content-Type的MIME類型

註:Express response documentation

路由

了解了HTTP請求的基本應用,而路由決定了由誰(指定腳本)去響應客戶端請求。

HTTP請求中,我們可以通過路由提取出請求的URL以及GET/POST參數。

接下來我們擴展Hello World,添加一些功能來處理更多類型的HTTP請求。

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
39
40
41
42
43
// express_demo2.js 文件
var express = require('express');
var app = express();
 
// 主頁輸出 "Hello World"
app.get('/', function (req, res) {
   console.log("主頁 GET 請求");
   res.send('Hello GET');
})
 
// POST 請求
app.post('/', function (req, res) {
   console.log("主頁 POST 請求");
   res.send('Hello POST');
})
 
// /del_user 頁面響應
app.get('/del_user', function (req, res) {
   console.log("/del_user 響應 DELETE 請求");
   res.send('刪除頁面');
})
 
// /list_user 頁面 GET 請求
app.get('/list_user', function (req, res) {
   console.log("/list_user GET 請求");
   res.send('用戶列表頁面');
})
 
// 對頁面 abcd, abxcd, ab123cd, 等響應 GET 請求
app.get('/ab*cd', function(req, res) {
   console.log("/ab*cd GET 請求");
   res.send('正則匹配');
})
 
 
var server = app.listen(8081, '0.0.0.0', function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("瀏覽地址為 http://%s:%s", host, port)
 
})

執行結果如下:

1
2
$ node express_demo2.js
瀏覽地址為 http://0.0.0.0:8081

開啟瀏覽器瀏覽:

1
2
3
4
5
http://0.0.0.0:8081
http://0.0.0.0:8081/del_user
http://0.0.0.0:8081/list_user
http://0.0.0.0:8081/abcd
http://0.0.0.0:8081/abcdefg

註:Express router documentation

靜態文件

Express提供了內置的中間件express.static來設置靜態文件。
如:images(圖片)、CSSJavaScript⋯⋯等。

你可以使用express.static中間件來設置靜態文件路徑。
例如:如果你將images(圖片)、CSSJavaScript文件放在public目錄下:

1
app.use('/public', express.static('public'));

public/images目錄下放些圖:

1
2
3
4
5
6
7
8
9
10
.
├── express_demo.js
├── express_demo2.js
├── node_modules
│   └── 省略
├── package-lock.json
├── package.json
└── public
└── images
└── blogger-logo.png
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// express_demo3.js 文件
var express = require('express');
var app = express();
 
app.use('/public', express.static('public'));
 
app.get('/', function (req, res) {
   res.send('Hello World');
})
 
var server = app.listen(8081, '0.0.0.0', function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("瀏覽地址為 http://%s:%s", host, port)
 
})

執行結果如下:

1
2
$ node express_demo3.js
瀏覽地址為 http://0.0.0.0:8081

開啟瀏覽器瀏覽:

1
http://0.0.0.0:8081/public/images/blogger-logo.png


註:以上參考了
Express
Node.js Express 框架
Node.js express 如何监听 IPv4 地址