middleware 中介軟體 官網說明:
Express 是一個本身功能極簡的路由與中介軟體 Web 架構:本質上,Express 應用程式是一系列的中介軟體函數呼叫。中介軟體函數是一些有權存取要求物件 (req) 、回應物件 (res) 和應用程式要求/回應循環中之下一個中介軟體函數的函數。下一個中介軟體函數通常以名為 next
的變數表示。
中介軟體函數可以執行下列作業:
執行任何程式碼。
對要求和回應物件進行變更。
結束要求/回應循環。
呼叫堆疊中的下一個中介軟體函數。
如果現行中介軟體函數不會結束要求/回應循環,它必須呼叫 next()
使用 app.use()
和 app.METHOD()
函數,將應用程式層次的中介軟體連結至 app object
實例,其中 METHOD 是中介軟體函數要處理的 HTTP 要求方法(例如 GET、PUT 或 POST),並採小寫。
如果有點抽象的話,可以當作 middleware 是一個守衛,可以顧及程式碼安全,所以 middleware 裡面可以寫一些安全性的程式邏輯,聽過 middleware 的把關後才會進入主要的程式碼。
基礎範例:
1 2 3 4 5 6 var app = express();app.use(function (req, res, next ) { console .log("Time:" , Date .now()); next(); });
範例練習 首先先登打下方程式碼,
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const express = require ("express" );const app = express();app.use((req, res, next ) => { console .log("這是 middleware" ); next(); }); app.get("/" , (req, res) => { res.send("<h1>這是 middleware 練習</h1>" ); }); const port = process.env.port || 3000 ;app.listen(port);
並在終端機運作 node app.js
,並且開啟 localhost:3000
,
會在終端機看到下方資訊:
terminal
瀏覽器會看到:
browser
可以看到會先讀到 middleware 的程式碼後,再執行 res 的內容在網頁上,相對的如果把 middleware 放在主要程式碼後面,那就失去 middleware 的功能。
404 頁面錯誤 為了提醒使用者可能輸入的路徑錯誤,所以現在網頁一定都要做 404 的錯誤頁面,可以看到會正確顯示頁面的是在根目錄的路由,如果路由任意輸入:
1 http://localhost :3000/thisiserrorurl
並且跑下方程式碼:
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const express = require ("express" );const app = express();app.use((req, res, next ) => { console .log("這是 middleware" ); next(); }); app.get("/" , (req, res) => { res.send("<h1>這是 middleware 練習</h1>" ); }); app.use((req, res, next ) => { res.status(404 ).send("404 Oops! 找不到網頁!" ); }); const port = process.env.port || 3000 ;app.listen(port);
這邊運作的過程會是,先透過 middleware 確認登入以及驗證通過後,發現沒有可以配對的路由,所以會直接跳到 404 的程式碼區塊,並且在網頁上顯示 404 Oops! 找不到網頁!
的字樣。
browser
dev tool Network
透過開發人員工具也會看到 404 的錯誤訊息。
500 error 程式錯誤 假設程式發生錯誤,例如在 middleware 有個未定義的函式(此範例是要演譯如果程式錯誤的情境,正規並不會這樣做,但可能會遇到 XD)。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const express = require ("express" );const app = express();app.use((req, res, next ) => { console .log("這是 middleware" ); notDefined(); next(); }); app.get("/" , (req, res) => { res.send("<h1>這是 middleware 練習</h1>" ); }); app.use((req, res, next ) => { res.status(404 ).send("404 Oops! 找不到網頁!" ); }); const port = process.env.port || 3000 ;app.listen(port);
執行後畫面會變這樣,
browser
但如果這樣呈現會被客戶打爆…
而 Express 也處理得很好,加上 500 error 的程式碼,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const express = require ("express" );const app = express();app.use((req, res, next ) => { console .log("這是 middleware" ); notDefined(); next(); }); app.get("/" , (req, res) => { res.send("<h1>這是 middleware 練習</h1>" ); }); app.use((req, res, next ) => { res.status(404 ).send("404 Oops! 找不到網頁!" ); }); app.use((err, req, res, next ) => { res.status(500 ).send("500 程式錯誤,請聯繫 IT 人員協助!" ); }); const port = process.env.port || 3000 ;app.listen(port);
此時重整畫面,網址與路徑還是要維持 localhost:3000/thisiserrorurl
,並且會看到畫面為:
browser
再看到 Network 也會出現 500 的資訊。
Network
middleware 可以獨立出來共用 如果 middleware 有需要共用的話,可以獨立拉出來變成一個函式,並且放在要執行的方法來讀取,得到的結果也會跟一開始的練習相同,程式碼如下:
app.js
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 const express = require ("express" );const app = express();function middleware (req, res, next ) { console .log("這是 middleware" ); next(); } app.get("/" , middleware, (req, res) => { res.send("<h1>這是 middleware 練習</h1>" ); }); app.use((req, res, next ) => { res.status(404 ).send("404 Oops! 找不到網頁!" ); }); app.use((err, req, res, next ) => { res.status(500 ).send("500 程式錯誤,請聯繫 IT 人員協助!" ); }); const port = process.env.port || 3000 ;app.listen(port);