Express 是一個 Web 應用框架,可以幫助我們快速搭建一個 Web 應用
1、Hello World
下面我們先來搭建一個簡單的小型應用,熟悉 Express 的基本使用方法
- 首先創建一個新文件夾作爲項目的根目錄,然後在該文件夾下打開命令行
- 然後使用
npm init
命令生成一個package.json
文件,它是項目的配置文件 - 接着使用
npm install --save express
命令安裝 Express,它會放在node_modules
目錄下 - 最後創建
server.js
文件,並在該文件中編寫如下代碼:
// 引入 Express 模塊
var express = require('express')
// 創建 Express 實例
var app = express()
// 設置路由
app.get('/', function (req, res) {
res.send('Hello World')
})
// 啓動服務器,監聽端口 5000
var server = app.listen(5000, '127.0.0.1', function() {
console.log('server running at http://127.0.0.1:5000')
})
上面就是一個簡單的應用程序,我們現在暫時還不需要理解其中的語法,等下將會逐一進行講解
最後打開命令行,輸入命令 node server.js
,打開 http://127.0.0.1:5000/ 即可看到 Hello World 的問候語
2、基礎路由設置
路由確定 應用程序如何響應特定的客戶端請求
每個路由都可以有一個或多個處理函數,這些函數在路由匹配時執行,語法格式如下:
app.METHOD(PATH, HANDLER)
其中,METHOD 表示請求方法,PATH 表示匹配路徑,HANDLER 表示路由匹配時的處理邏輯
以下面的代碼爲例,當客戶端以 GET 方法請求根路徑資源時,執行匿名函數,發送 Hello World 響應
app.get('/', function (req, res) {
res.send('Hello World')
})
(1)METHOD
METHOD 定義請求方法,Express 支持所有 HTTP 請求方法,下面是一些例子:
-
app.get(PATH, HANDLER)
定義當使用 GET 方法請求 PATH 路徑上的資源時執行邏輯 HANDLER -
app.post(PATH, HANDLER)
定義當使用 POST 方法請求 PATH 路徑上的資源時執行邏輯 HANDLER -
app.all(PATH, HANDLER)
定義當使用任何方法請求 PATH 路徑上的資源時執行邏輯 HANDLER
(2)PATH
PATH 定義匹配路徑,它可以是字符串、字符串模式或正則表達式,下面是一些例子:
-
'/about'
匹配請求路徑 /about -
'/ab?cd'
匹配請求路徑 /acd、/abcd(?:匹配 ? 前的字符 0 次或 1次) -
'/ab+cd'
匹配請求路徑 /abcd,/abbcd 等等(+:匹配 + 前的字符 1 次或多次) -
/a/
匹配任意包含字符 a 的請求路徑(使用正則表達式幾乎可以滿足一切複雜的需求)
我們還可以在路徑中 指定參數,參數以 :
爲前綴,用於捕獲指定位置的值,並將其保存在 req.params
中
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World')
})
app.get('/firstname/:firstname/lastname/:lastname', function (req, res) {
let params = req.params
let result = params.firstname + ' ' + params.lastname
res.send(result)
})
var server = app.listen(5000, '127.0.0.1', function() {
console.log('server running at http://127.0.0.1:5000')
})
/*
* 執行結果:
* 如果訪問網址 http://127.0.0.1:5000
* 那麼就會返回 Hello World
* 如果訪問網址 http://127.0.0.1:5000/firstname/Steve/lastname/Jobs
* 那麼就會返回 Steve Jobs
**/
(3)HANDLER
HANDLER 是路由匹配時的處理邏輯,它可以是函數、函數數組或兩者的組合形式
在使用多組函數時,必須確保使用 next()
方法將控制權傳遞給後續函數,否則將會直接終止
var express = require('express')
var app = express()
var sayHello = function (req, res) {
res.send('Hello World')
}
var reverseMessage = function(req, res) {
let message = req.params.message
let reverse = message.split('').reverse().join('')
res.send(reverse)
}
var showParams = function (req, res, next) {
let params = req.params
console.log('---Params')
for (let prop in params) {
console.log(prop + ': ' + params[prop])
}
console.log('---------')
next()
}
app.get('/', sayHello)
app.get('/reverse/:message', [showParams, reverseMessage])
var server = app.listen(5000, '127.0.0.1', function() {
console.log('server running at http://127.0.0.1:5000')
})
一般情況下,函數帶有兩個參數,分別是 Request 和 Response 對象,用於處理請求和響應數據
Request 對象 常見的屬性和方法有:
屬性和方法 | 描述 |
---|---|
ip | IP 地址 |
originalUrl | 原始 URL |
baseURL | 基礎 URL |
protocol | 協議類型 |
hostname | 主機名 |
subdomains | 子域名 |
path | 資源路徑 |
query | 查詢字符串 |
route | 當前匹配路由 |
params | 路由參數,用於獲取 GET 請求的內容 |
body | 當使用 body-parser 中間件時,包含請求主體,用於獲取 POST 數據 |
cookies | 當使用 cookie-parser 中間件時,包含 Cookie 對象,用於獲取 Cookie 內容 |
get(field) |
獲取指定的 HTTP 請求頭 |
Response 對象 常見的屬性和方法有:
屬性和方法 | 描述 |
---|---|
set(field[,value]) |
設置 HTTP 響應頭 |
get(field) |
返回 HTTP 響應頭 |
append(field[,value]) |
添加 HTTP 響應頭 |
cookie(name,value[,option]) |
設置 Cookie |
clearCookie(name[,options]) |
清除 Cookie |
redirect([status,]path) |
重定向到指定路徑 |
send([body]) |
傳送響應 |
sendStatus(code) |
傳送狀態碼 |
sendFile(path[,options][,fn]) |
傳送文件 |
json([body]) |
傳送 JSON 數據 |
jsonp([body]) |
傳送 JSONP 數據 |
end([data][,encoding]) |
結束響應 |
3、高級路由設置
(1)app.route()
如果需要爲同一路徑的不同請求方法定義不同的處理函數,app.route(path)
是一個不錯的選擇
app.route('/book')
.get(function (req, res) {
res.send('Get a book')
})
.post(function (req, res) {
res.send('Add a book')
})
.put(function (req, res) {
res.send('Update the book')
})
(2)express.Router()
express.Router([options])
用於創建 Router 實例,它就像 express 的實例一樣,可以添加路由和中間件
我們可以創建一個路由文件 router.js
,並在文件中編寫如下代碼:
var express = require('express')
var router = express.Router()
// 添加中間件
router.use((req, res, next) => {
console.log('執行路由: ' + Date.now())
next()
})
// 添加路由
router.get('/', (req, res, next) => {
res.send('Home Page')
})
router.get('/about', (req, res, next) => {
res.send('About Page')
})
module.exports = router
然後,我們可以在應用程序 server.js
中加載路由文件,代碼如下:
var express = require('express')
var router = require('./router')
var app = express()
app.use('/router', router)
var server = app.listen(5000, '127.0.0.1', function() {
console.log('server running at http://127.0.0.1:5000')
})
4、中間件函數
中間件 (Middleware) 實際上是一個 函數,可以訪問請求對象 Request,響應對象 Response 以及 next 函數
中間件的加載順序十分重要,先加載的中間件先執行,中間件可以分爲以下幾種類別
- 應用程序級中間件:通過
app.METHOD()
方法和app.use()
方法綁定到 express 實例
var express = require('express')
var app = express()
// 由於沒有指定路徑,所以每個請求都會執行該中間件函數
app.use(function (req, res, next) { // 中間件函數
console.log('Time: ' + Date.now())
next()
})
app.get('/user/:id', function (req, res, next) { // 中間件函數
res.send('Hello, ' + req.params.id)
})
var server = app.listen(5000, '127.0.0.1', function() {
console.log('server running at http://127.0.0.1:5000')
})
-
路由器級中間件:通過
router.METHOD()
方法和router.use()
方法綁定到 Router 實例它與應用程序級中間件的工作方式相同
var express = require('express')
var router = express.Router()
router.use(function (req, res, next) { // 中間件函數
console.log('Time: ' + Date.now())
next()
})
router.get('/user', function (req, res) { // 中間件函數
res.send('Hello, ' + req.params.id)
})
var app = express()
app.use('/virtual', router)
var server = app.listen(5000, '127.0.0.1', function() {
console.log('server running at http://127.0.0.1:5000')
})
-
錯誤處理中間件:與應用程序級中間件和路由器級中間件的定義方式相同
區別在於錯誤處理中間件的參數有四個,分別是
function(err, req, res, next)
app.use(function(err, req, res, next) {
console.error(err.stack)
res.status(500).send('Error!')
})
-
內置中間件:常用的內置中間件是
express.static()
,將會在下面進行介紹 -
第三方中間件:常用的第三方中間件可以參考 官方文檔
5、靜態文件
Express 內置的中間件函數 express.static()
可以 掛載圖片、CSS 和 JS 之類的靜態文件,語法格式如下:
express.static(root, [options])
其中,root 表示儲存靜態文件的根目錄路徑,options 是一個對象,用於提供更詳細的信息
我們創建一個項目,其中 public
目錄用於儲存靜態文件,server.js
文件是程序的主入口,目錄結構如下:
+ app
+ node_module
+ public
+ images
- icon.png
- background.png
- index.html
- style.css
- script.js
- server.js
- package.json
我們可以在 server.js
文件中聲明 public
目錄下的內容開放,如此客戶端就可以通過地址直接請求資源
例如 http://127.0.0.1:5000/images/icon.png、http://127.0.0.1:5000/hello.html 等
app.use(express.static('public'))
如果需要創建 虛擬路徑前綴,可以在掛載時指定,這樣客戶端就需要在原有路徑前添加虛擬前綴纔可訪問資源
例如 http://127.0.0.1:5000/static/images/icon.png、http://127.0.0.1:5000/static/hello.html 等
app.use('/static', express.static('public'))
【 閱讀更多 Node.js 系列文章,請看 Node.js學習筆記 】