官术网_书友最值得收藏!

2.3 Koa的中間件

中間件是Koa中一個非常重要的概念。Koa應用程序其實就是一個包含一組中間件函數(shù)的對象,而且有了async/await這種高級語法糖,使中間件寫起來更加簡單。

2.3.1 中間件概念

先來看下面這段代碼:

上述代碼是Koa應用程序的一個簡單的“Hello World”示例,可以把其中打印日志的部分單獨抽象成一個logger函數(shù),代碼如下:

抽象出來的logger函數(shù)就是中間件,通過app.use()函數(shù)來加載中間件。

中間件函數(shù)是一個帶有ctx和next兩個參數(shù)的簡單函數(shù)。ctx就是之前章節(jié)介紹的上下文,封裝了Request和Response等對象;next用于把中間件的執(zhí)行權(quán)交給下游的中間件。在next()之前使用await關鍵字是因為next()會返回一個Promise對象,而在當前中間件中位于next()之后的代碼會暫停執(zhí)行,直到最后一個中間件執(zhí)行完畢后,再自下而上依次執(zhí)行每個中間件中next()之后的代碼,類似于一種先進后出的堆棧結(jié)構(gòu)。這里用官方給出的 “洋蔥模型”示意圖(如圖2.1所示)來解釋中間件的執(zhí)行順序。

圖2.1 “洋蔥模型”示意圖

圖2.1形象地展示了中間件的執(zhí)行順序。下面通過具體代碼來演示中間件的執(zhí)行,如下所示:

這段代碼中有3個中間件,執(zhí)行結(jié)果如下:

如果想將多個中間件組合成一個單一的中間件,便于重用或?qū)С觯梢允褂胟oa-compose,代碼如下:

Koa應用程序中的大部分功能都是通過中間件實現(xiàn)的,寫好中間件也是學好Koa的必經(jīng)之路。當然,也可以使用很多成熟的中間件模塊來完善Koa應用,而且利用成熟的中間件模塊也能大大提升開發(fā)效率。

2.3.2 實戰(zhàn)演練:使用中間件獲取響應時間(視頻演示)

在實戰(zhàn)項目中,經(jīng)常需要記錄服務器的響應時間,響應時間指的是從服務器接收到HTTP請求到最終返回給客戶端之間所耗的時長。在Koa應用中,利用中間件機制可以很方便地實現(xiàn)這一功能,代碼如下:

執(zhí)行上述代碼,控制臺打印顯示如下:

然后打開瀏覽器,訪問http://localhost:3000,控制臺顯示內(nèi)容更新如下:

當服務器接收到HTTP請求后,會以“洋蔥模型”的方式開始流轉(zhuǎn)。先進入第1個中間件,在上述代碼中,第1個中間件會記錄下當前時間戳,然后將控制權(quán)向下傳遞,第2、第3個中間件進行相應的邏輯處理……最后再一層層地返回,直到返回給第1個中間件,再次記錄下當前的時間戳。所記錄的兩次時間戳之間的差值,即為此次HTTP請求的響應時間。

細心的讀者會發(fā)現(xiàn),控制臺打印了兩條記錄,這是因為訪問http://localhost:3000后,DOM(Document Object Model,文檔對象模型)結(jié)構(gòu)在瀏覽器上進行渲染,會發(fā)起相應的靜態(tài)資源文件的HTTP請求,/favicon.ico即為DOM渲染時默認自帶的靜態(tài)資源。

另外,讀者可以思考一下,如果一個中間件沒有調(diào)用await next(),又會發(fā)生什么情況呢?答案是:后面的中間件將不會被執(zhí)行。讀者可以自行驗證一下。

本節(jié)在線視頻地址為https://camp.qianduan.group/koa2/2/1/2,二維碼:

2.3.3 常用Koa中間件介紹

利用成熟的中間件來構(gòu)建Koa應用能大大提高開發(fā)效率。GitHub上的Koa社區(qū)提供了很多有用的中間件,讀者可以訪問https://github.com/koajs/koa/wiki進行搜索。本節(jié)主要介紹幾個常用的中間件。

1.koa-bodyparser中間件

在2.2.2節(jié)中,有一個獲取POST請求參數(shù)的例子,使用了Node.js的req對象監(jiān)聽data事件來獲取,這種方法比較煩瑣。koa-bodyparser中間件可以把POST請求的參數(shù)解析到ctx.request.body中。使用koa-bodyparser中間件首先需要安裝,安裝命令如下:

接下來看一個使用koa-bodyparser中間件解析POST請求參數(shù)的實際例子,代碼如下:

運行上述代碼,并在瀏覽器中訪問http://localhost:3000/會看到一個登錄表單,如圖2.2所示。

圖2.2 登錄表單

此處為了演示方便,未對用戶名和密碼做任何校驗,所以可以在輸入任意用戶名和密碼之后單擊“submit”按鈕,就會在頁面上顯示所填寫的用戶名和密碼,如下所示:

從這個結(jié)果可以知道,koa-bodyparser中間件最終解析出來的參數(shù)是一個對象。

2.koa-router中間件

上面登錄表單的例子通過ctx.url判斷路徑,通過ctx.method判斷請求的方法,這種手動判斷路由的方式仍然比較麻煩,需要寫很多的代碼。如果借助koa-router中間件就能減少很多代碼量。首先要安裝koa-router,命令如下:

安裝完成之后,用koa-router中間件改造之前的代碼,代碼如下:

經(jīng)過改造之后的代碼運行效果和之前是一樣的,但是寫法和代碼都更精簡,可讀性也更高。(上述代碼省略了繪制登錄頁和解析formData數(shù)據(jù)的部分,這部分代碼沒變,從上一個例子中復制過來即可)。

3.koa-static中間件與koa-views中間件

上面的例子簡化了路由的寫法,但是把HTML代碼直接寫在中間件中純粹是為了演示方便。在實際開發(fā)中,不但會把HTML模板寫在單獨的文件中,還會引用單獨的CSS樣式及JavaScript文件,這時就需要用到koa-static和koa-views中間件。koa-static是專門用于加載靜態(tài)資源的中間件,通過它可以為頁面請求加載CSS、JavaScript等靜態(tài)資源,而koa-views用于加載HTML模板文件。

下面使用koa-static和koa-views繼續(xù)改寫上面的例子,首先安裝koa-static和koa-views,命令如下:

安裝完成之后來寫核心代碼,示例代碼如下(完整代碼請在GitHub上查看):

從上述代碼中可以看出,之前直接寫在中間件中的HTML代碼被提取了出來,進一步簡化了代碼結(jié)構(gòu),并且還在HTML代碼中引入了一個修改按鈕樣式的CSS文件和一個顯示alert彈窗的JavaScript文件,運行結(jié)果如圖2.3所示。

圖2.3 登錄表單和彈窗

以上是Koa中最常用的4個中間件。通過不斷加入新的中間件,app.js中的代碼變得越來越簡潔和健壯。善用成熟中間件來開發(fā)Koa應用是必修課。Koa還有很多其他常用的中間件,后面的章節(jié)會詳細介紹其他常用中間件的使用方法,這里不再一一贅述。

主站蜘蛛池模板: 鲜城| 固镇县| 宝丰县| 双流县| 泾源县| 北票市| 汪清县| 镇江市| 湘潭市| 共和县| 格尔木市| 鞍山市| 木里| 炉霍县| 安仁县| 忻州市| 英德市| 武强县| 中方县| 高雄县| 吴忠市| 青州市| 垦利县| 江门市| 凤城市| 张家界市| 称多县| 大安市| 抚远县| 临沭县| 汝州市| 巩留县| 巧家县| 台江县| 恩平市| 葫芦岛市| 无为县| 五寨县| 稻城县| 和田县| 常州市|