亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網
    最全最豐富的資訊網站

    Node.js 中間件的工作原理

    Node.js 中間件的工作原理

    什么是 Express 中間件?

    • 中間件在字面上的意思是你在軟件的一層和另一層中間放置的任何東西。
    • Express 中間件是在對 Express 服務器請求的生命周期內所執(zhí)行的函數。
    • 每個中間件都可以訪問其被附加到的所有路由的 HTTP 請求和響應。
    • 另外,中間件可以終止 HTTP 請求,也可以用 next 將其傳遞給另一個中間件函數。中間件的這種“鏈”使你可以對代碼進行劃分并創(chuàng)建可重用的中間件。

    編寫 Express 中間件的要求

    你需要安裝一些東西來創(chuàng)建、使用和測試 Express 中間件。首先需要 Node 和 NPM。為確保已經安裝,可以運行:

    npm -v && node -v

    你應該看到已安裝的 Node 和 NPM 版本。如果出現錯誤,則需要安裝 Node。所有例子都應在 Node ver 8+ 和NPM ver 5+ 下使用。

    本文使用了 Express 4.x 版。這很重要,因為從 3.x 版到 4.x 版有重大的更改。

    Express中間件:基礎

    首先我們使用 Express 最基本的內置中間件。創(chuàng)建一個新項目并 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服務器響應用戶之前對其進行修改。這些對象通??s短為 req,res。

    中間件函數是使用相關信息修改 reqres 對象的理想場所。例如用戶登錄后,你可以從數據庫中獲取其用戶詳細信息,然后將這些詳細信息存儲在 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     } }

    如果出現錯誤,并且你不想執(zhí)行其他代碼,則不要調用該函數。請記住在這種情況下要發(fā)送響應,否則客戶端將會等待響應直到超時。

    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 收到請求后,與請求相匹配的每個中間件都將會按照初始化的順序運行,直到有終止操作為止。

    Node.js 中間件的工作原理

    因此,如果發(fā)生錯誤,則將按順序調用所有用于處理錯誤的中間件,直到其中一個不再調用 next() 函數調用為止。

    Express中間件的類型

    • 路由器級中間件,例如:router.use
    • 內置中間件,例如:express.static,express.json,express.urlencoded
    • 錯誤處理中間件,例如:app.use(err,req,res,next)
    • 第三方中間件,例如:bodyparser、cookieparser
    • 路由器級中間件
    • express.Router 使用 express.Router 類創(chuàng)建模塊化的、可安裝的路由處理。路由實例是一個完整的中間件和路由系統(tǒng)。

      • 你可以用中間件進行日志記錄、身份驗證等操作。如下所示,以記錄用戶的最新活動并解析身份驗證標頭,用它確定當前登錄的用戶并將其添加到 Request 對象。
      • 該函數在程序每次收到請求時執(zhí)行。如果有錯誤,它會僅結束響應,而不會調用后續(xù)的中間件或路由處理。
    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 提供靜態(tài)資源,例如 HTML 文件,圖像等。
    • express.json 負載解析用 JSON 傳入的請求。
    • express.urlencoded 解析傳入的用 URL 編碼的有效載荷請求。

    錯誤處理中間件

    錯誤處理中間件始終采用四個參數(err,req,res,next)。你必須通過提供四個參數來將其標識為錯誤處理中間件函數。即使你不需要使用 next 對象,也必須指定。否則 next 對象將被解釋為常規(guī)中間件,并將會無法處理錯誤?;竞灻缦滤荆?/p>

    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 屬性。這只是檢查響應是否已經將標頭發(fā)送到客戶端。如果還沒有,它將向客戶端發(fā)送 HTTP 500 狀態(tài)和錯誤消息。

    例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); });
    • 在這種情況下,中間件檢查是否拋出了 404(not found)錯誤。如果是,它將渲染 “NotFound” 模板頁面,然后將錯誤傳遞到中間件中的下一項。
    • 下一個中間件檢查是否拋出了 304(unauthorized)錯誤。如果是,它將渲染“Unauthorized”頁面,并將錯誤傳遞到管道中的下一個中間件。
    • 最后,“catch all” 錯誤處理僅記錄錯誤,如果未發(fā)送響應,它將發(fā)送錯誤的 httpStatusCode(如果未提供則發(fā)送 HTTP 500 狀態(tài))并渲染 “UnknownError” 模板。

    第三方級別的中間件

    在某些情況下,我們將向后端添加一些額外的功能。先安裝 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 服務器的重要組成部分,并且非常有用。

    贊(0)
    分享到: 更多 (0)
    網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號