你需要安裝一些東西來建立、使用和測試 Express 中介軟體。首先需要 Node 和 NPM。為確保已經安裝,可以執行:
npm -v && node -v
你應該看到已安裝的 Node 和 NPM 版本。如果出現錯誤,則需要安裝 Node。所有例子都應在 Node ver 8+ 和NPM ver 5+ 下使用。
本文使用了 Express 4.x 版。這很重要,因為從 3.x 版到 4.x 版有重大的更改。
首先我們使用 Express 最基本的內建中介軟體。建立一個新專案並 npm 初始化它…
npm init npm install express --save Create server.js and paste the following code: const express = require('express'); const app = express(); app.get('/', (req, res, next) => { res.send('Welcome Home'); }); app.listen(3000);
假設你在 web 網路伺服器上正在使用 Node.js 和 Express 執行Web應用程式。在此應用中,你需要登入的某些頁面。
當 Web 伺服器收到資料請求時,Express 將為你提供一個請求物件,其中包含有關使用者及其所請求資料的資訊。 Express 還使你可以存取響應物件,可以在Web伺服器響應使用者之前對其進行修改。這些物件通常縮短為 req,res。
中介軟體函數是使用相關資訊修改 req 和 res 物件的理想場所。例如使用者登入後,你可以從資料庫中獲取其使用者詳細資訊,然後將這些詳細資訊儲存在 res.user
中。
async function userMiddleware (req, res, next) { try { const userData = await getUserData(req.params.id); //see app.get below if(userData) { req.user = userData; next(); } } catch(error) { res.status(500).send(error.message); //replace with proper error handling } }
如果出現錯誤,並且你不想執行其他程式碼,則不要呼叫該函數。請記住在這種情況下要傳送響應,否則使用者端將會等待響應直到超時。
var app = express(); //your normal route Handlers app.get('/user/:id', userMiddleware, userController);
你可以在中介軟體陣列中或著通過使用多個 app.use
呼叫來連結中介軟體:
app.use(middlewareA); app.use(middlewareB); app.get('/', [middlewareC, middlewareD], handler);
Express 收到請求後,與請求相匹配的每個中介軟體都將會按照初始化的順序執行,直到有終止操作為止。
因此,如果發生錯誤,則將按順序呼叫所有用於處理錯誤的中介軟體,直到其中一個不再呼叫 next() 函數呼叫為止。
express.Router 使用 express.Router 類建立模組化的、可安裝的路由處理。路由範例是一個完整的中介軟體和路由系統。
var router = express.Router() //Load router-level middleware by using the router.use() and router.METHOD() functions. //The following example creates a router as a module, loads a middleware function in it, // defines some routes, and mounts the router module on a path in the main app. var express = require(‘express’); var router = express.Router(); // a middleware function with no mount path. This code is executed for // every request to the router // logging async function logMiddleware (req, res, next) { try { console.log(req.user.id, new Date()); next(); } catch() { res.status(500).send(error.message); } } // authentication async function checkAuthentication(req, res, next) => { // check header or url parameters or post parameters for token const token = req.body.token || req.query.token || req.headers['x-access-token'] || req.headers['authorization']; if (token) { try { // verifies secret req.decoded = await jwt.verify(token, config.secret) let checkUser = await authenticateTokenHelper.getUserDetail(req); // if everything is good, save to request for use in other routes if (checkUser) { req.user = req.decoded next() } else { return res.status(403).json({ message: responseMessage.noAuthorized }) } } catch (err) { return res.status(401).json({ message: responseMessage.invalidToken }) } } else { // if there is no token return res.status(400).json({ message: responseMessage.invalidRequest }) } } router.use(logMiddleware); router.get('/user, checkAuthentication, handler);
Express 有以下內建的中介軟體功能:
express.static
提供靜態資源,例如 HTML 檔案,影象等。express.json
負載解析用 JSON 傳入的請求。express.urlencoded
解析傳入的用 URL 編碼的有效載荷請求。錯誤處理中介軟體始終採用四個引數(err,req,res,next)。你必須通過提供四個引數來將其標識為錯誤處理中介軟體函數。即使你不需要使用 next 物件,也必須指定。否則 next 物件將被解釋為常規中介軟體,並將會無法處理錯誤。基本簽名如下所示:
app.use(function (err, req, res, next) { console.error(err.stack) res.status(500).send('Something broke!') })
例1:
app.get('/users', (req, res, next) => { next(new Error('I am passing you an error!')); }); app.use((err, req, res, next) => { console.log(err); if(!res.headersSent){ res.status(500).send(err.message); } });
在這種情況下,管道末端的錯誤處理中介軟體將會處理該錯誤。你可能還會注意到,我檢查了 res.headersSent
屬性。這只是檢查響應是否已經將檔頭傳送到使用者端。如果還沒有,它將向用戶端傳送 HTTP 500 狀態和錯誤訊息。
例2:
你還可以連結錯誤處理中介軟體。通常以不同的方式處理不同型別的錯誤:
app.get('/users, (req, res, next) => { let err = new Error('I couldn\'t find it.'); err.httpStatusCode = 404; next(err); }); app.get('/user, (req, res, next) => { let err = new Error('I\'m sorry, you can\'t do that, Dave.'); err.httpStatusCode = 304; next(err); }); app.use((err, req, res, next) => { // handles not found errors if (err.httpStatusCode === 404) { res.status(400).render('NotFound'); } // handles unauthorized errors else if(err.httpStatusCode === 304){ res.status(304).render('Unauthorized'); } // catch all else if (!res.headersSent) { res.status(err.httpStatusCode || 500).render('UnknownError'); } next(err); });
在某些情況下,我們將向後端新增一些額外的功能。先安裝 Node.js 模組獲取所需的功能,然後在應用級別或路由器級別將其載入到你的應用中。
範例:當 body-parser 處理 Content-Type 請求檔頭時,所有中介軟體都將使用解析的正文填充 req.body
屬性。
const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.urlencoded({extended:false})) app.use(bodyParser.json()) app.post('/save',(req,res)=>{ res.json({ "status":true, "payload":req.body }) } app.listen(3000,(req,res)=>{ console.log('server running on port') })
中介軟體功能是一種非常好的方式,可以對每個請求或針對特定路由的每個請求執行程式碼,並對請求或響應資料採取措施。中介軟體是現代 Web 伺服器的重要組成部分,並且非常有用。
更多程式設計相關知識,請存取:!!
以上就是Node.js 中介軟體的工作原理的詳細內容,更多請關注TW511.COM其它相關文章!