摘要:框架中間件作為的老牌框架是現有框架中最全面的。然而在學習除了那些之外,對于框架最重要的就是中間件這個概念了。中間件功能可以執行以下任務執行任何代碼對請求和響應對象進行更改。結束請求響應周期。調用堆棧中的下一個中間件。
express.js框架中間件(middleware)
_express.js_作為_Node.js_的老牌框架,是現有框架中最全面的。然而在學習express除了那些api之外,對于框架最重要的就是__中間件__這個概念了。如果理解了,就可以把這個框架玩活了,項目開發肯定會更加順利,而且還可以開發很多額外的功能,甚至中間件擴展開發。
但是就這么一個東西,是很多學習node.js的小萌新們就算寫出一個博客項目,都不知道它到底有啥作用。我當時在理解的時候也花了不少功夫,趁著沒有啥工作,給各位學習express.js的一點點我的指導意見。當然,這里面可能也有koa2和egg的忠實粉絲,但其實所有node框架貌似都有這個概念,所以我用express舉例子,希望各位將就一下哈,應該都是可以看得懂的。
首先我先來一波官方的解釋:
好吧,被這些英語嚇到了,來一波譯文:
[中間件函數是可以訪問請求對象(req)、響應對象(res)和應用程序請求響應周期中的下一個函數的函數。下一個函數是Express路由器中的一個函數,當調用該函數時,它執行當前中間件之后的中間件。
中間件功能可以執行以下任務:
執行任何代碼
對請求和響應對象進行更改。
結束請求響應周期。
調用堆棧中的下一個中間件。
終于知道當初的我為毛剛開始理解的時候很困難了,說實在的看得我真的有懵的。幸好,我還是從這個坑爬出來了,我來拉你們一把了。首先我們不去深究概念,直接上一個代碼塊。
如果我們啟動服務,訪問"/"路由,會返回"這是一個根路由",訪問router1路由就會得到這是一個"這是一個router1路由的"的信息。這看起來是一個很簡單的路由查詢,我們理一下過程,這個請求是如何訪問到這個路由的呢。
一般來說,一個express框架的項目會寫入很多路由,但各位要注意的是,這個請求并不是直接定位到這個路由的,而是一個從上至下匹配的一個過程。
有點亂?沒關系我們看圖
我們看到這幅圖,有一個箭頭,從上到下的。什么意思呢,如果用戶發了一個這樣的請求
GET "/router7"
那么他會從第一個開始一個一個去匹配,知道發現有一個路由名和請求方法都一致的路由,就立馬執行里面的代碼,并且返回一段文字"這是一個router7路由"。這都很好理解,那么現在我有一個需求,就是不管訪問任何一個路由,我都要知道這個訪問者的ip地址和訪問的目標路由打印出來,生產訪問日志。那么怎么做了。
我們分析一波,這段程序是所有的請求都要執行的,如果按照執行順序的說法,那么這段程序是應該放到所有路由的最前面的,也就是說這段程序是所有路由要經過的一段程序,也就是我們所說的中間件。好的,廢話不多說,上代碼
const fs = require("fs") const log = (req,res) => { const ip = req.ip, route = req.route.path const log = `ip:${ip} path:${route}` fs.writeFileSync(__dirname + "/log",log) }
比如現在我有一個log函數,它專門用來記錄訪問日志的。如何所有的都一起執行了,我們加一段這樣的代碼
app.use(log)
它加在所有代碼的最上面,但是不是加上就完事了,還必須在log函數里面再加一段代碼,不然當程序執行到里面之后就出不去了,什么代碼了。我們重寫log函數
const log = (req,res,next) => { const ip = req.ip, route = req.route.path const log = `ip:${ip} path:${route}` fs.writeFileSync(__dirname + "/log",log) next() }
大家有沒有看見那個next,它有什么作用了。前面我們提到,它其實就是一個過渡者,主要的作用其實就是經過之后,要繼續往下面執行,還是就此終止返回結果。
說的簡單一點,就是我們一個http請求,到達我們的node服務器之后,要經歷的過程,而每經過一個程序塊,就是個中間件,每一個中間件只要有next就會傳遞到下一個中間件里面,直到服務器res響應結果,整個路由就此結束。
我們整合一下代碼。并且精簡一下,也跑一遍程序
const express = require("express") const app = express() const log = (req,res,next) => { const ip = req.ip, route = req.route.path const log = `ip:${ip} path:${route}` fs.writeFileSync(__dirname + "/log",log) next() } app.use(log)//任何請求都會經過這個log中間件 app.get("/", (req, res) => { console.log(req.route.stack) res.send("這是一個根路由!") }) app.get("/router1", (req, res) => { res.send("這是一個router1路由!") }) app.get("/router2", (req, res) => { res.send("這是一個router2路由!") }) app.listen(3000, () => { console.log("app listening on port 3000!") })
GET "/router2" //打印日志,并且返回結果
這就是一個簡單的中間件解釋了。大家也可以回去看看你原來寫過的代碼,是否對之前的use這個玩意有點啟發了?
我是小龍,希望對大家有所幫助
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103229.html
摘要:原文譯者如果你曾經去過一個坐下來就餐的餐廳,那么你可以了解的基礎知識。而且由于缺少路徑,它將在每個請求上運行。這就是路由的來源。到目前為止,你已經雇傭了一位經理,在接受客戶請求之前定義了要做的事情,并且確定如何處理特定的客戶請求。 showImg(https://segmentfault.com/img/bVYnBo?w=4000&h=2666); 原文:Going out to e...
摘要:入口文件在文件夾下的,其向外界暴露了一些方法。方法也是從中繼承的。入口文件很清晰,主要是完成方法的暴露以及的一些初始化操作。下一篇寫寫路由的實現。 還沒用express寫過server,先把部分源碼擼了一遍,各位大神求輕拍。 express入口文件在lib文件夾下的express.js,其向外界暴露了一些方法。 最主要的(express.js 第36-47行): function cr...
摘要:在后續的總結中,我會繼續分析,并準備將一些值得分析的逐一解讀,也會涉及一些。從一個官方示例開始這是官方給出的一個簡單程序,運行后訪問顯示。第一行載入了框架,我們來看源代碼中的。代碼的開始定義了一個函數,函數有形參,,為回調函數。 這兩天仔細看了看express的源碼,對其的整個實現有了較清晰的認識,所以想總結一下寫出來,如果有什么不對的地方,望指出。 這是第一篇,首先介紹一個最簡單的...
摘要:關于的實現源碼解讀,版本為。主要為路由部分。返回到的遍歷是通過尾遞歸的方式實現的,注意到被傳入的方法中,中處理事情最后向傳入,從而是否繼續遍歷取決于的實現是否調用的方法。 關于express.js的實現源碼解讀,版本為 4.14。主要為路由部分。 一個Web框架最重要的模塊是路由功能,該模塊的目標是:能夠根據method、path匹配需要執行的方法,并在定義的方法中提供有關請求和回應的...
摘要:框架核心特性路由定義了路由表用于執行不同的請求動作。中間件可以設置中間件來響應請求。注冊一個請求路由結束響應開啟監聽端口執行上面代碼是一種實用工具,將為您的源的任何變化并自動重啟服務器監控。 Express 簡介 Express 是一個簡潔而靈活的 node.js Web應用框架, 提供了一系列強大特性幫助你創建各種 Web 應用,和豐富的 HTTP 工具。使用 Express 可以快...
閱讀 1602·2021-11-02 14:48
閱讀 3657·2019-08-30 15:56
閱讀 2770·2019-08-30 15:53
閱讀 3214·2019-08-30 14:09
閱讀 3101·2019-08-30 12:59
閱讀 2857·2019-08-29 18:38
閱讀 2697·2019-08-26 11:41
閱讀 2215·2019-08-23 16:45