搜尋
首頁web前端js教程Node.js 中間件的工作原理

Node.js 中間件的工作原理

Sep 30, 2020 pm 06:01 PM
node.js中介軟體

Node.js 中間件的工作原理

影片教學推薦:node js教學

什麼是Express 中間件?

  • 中間件在字面上的意思是你在軟體的一層和另一層中間放置的任何東西。
  • Express 中間件是在 Express 伺服器請求的生命週期內所執行的函數。
  • 每個中間件都可以存取其被附加到的所有路由的 HTTP 請求和回應。
  • 另外,中間件可以終止 HTTP 請求,也可以用 next 將其傳遞給另一個中間件函數。中間件的這種「鏈」使你可以將程式碼劃分並創建可重複使用的中間件。

寫 Express 中間件的要求

你需要安裝一些東西來建立、使用和測試 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 最基本的內建中間件。建立一個新專案並 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伺服器回應使用者之前對其進行修改。這些物件通常會縮短為 reqres

中間件函數是使用相關資訊修改 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
    }
}

如果發生錯誤,並且你不想執行其他程式碼,則不要呼叫該函數。請記住在這種情況下要發送回應,否則客戶端將會等待回應直到逾時。

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 中間件的工作原理

因此,如果發生錯誤,則會依序呼叫所有用於處理錯誤的中間件,直到其中一個不再呼叫next()函數呼叫為止。

Express中間件的型別

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

    • 你可以用中間件進行日誌記錄、驗證等操作。如下所示,以記錄使用者的最新活動並解析身分驗證標頭,用它來確定目前登入的使用者並將其新增至 Request 物件。
    • 該函數在程式每次收到請求時執行。如果有錯誤,它會僅結束回應,而不會呼叫後續的中間件或路由處理。
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);
});
  • 在这种情况下,中间件检查是否抛出了 404(not found)错误。如果是,它将渲染 “NotFound” 模板页面,然后将错误传递到中间件中的下一项。
  • 下一个中间件检查是否抛出了 304(unauthorized)错误。如果是,它将渲染“Unauthorized”页面,并将错误传递到管道中的下一个中间件。
  • 最后,“catch all” 错误处理仅记录错误,如果未发送响应,它将发送错误的 httpStatusCode(如果未提供则发送 HTTP 500 状态)并渲染 “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 服务器的重要组成部分,并且非常有用。

更多编程相关知识,请访问:编程入门!!

以上是Node.js 中間件的工作原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:thirdrocktechkno。如有侵權,請聯絡admin@php.cn刪除
JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),