成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說對中間件概念的理解,如何封裝 node 中間件?

系統
中間件(Middleware)是介于應用系統和系統軟件之間的一類軟件,它使用系統軟件所提供的基礎服務(功能),銜接網絡上應用系統的各個部分或不同的應用,能夠達到資源共享、功能共享的目的。

[[405569]]

本文轉載自微信公眾號「JS每日一題」,作者灰灰。轉載本文請聯系JS每日一題公眾號。

 

一、是什么

中間件(Middleware)是介于應用系統和系統軟件之間的一類軟件,它使用系統軟件所提供的基礎服務(功能),銜接網絡上應用系統的各個部分或不同的應用,能夠達到資源共享、功能共享的目的

在NodeJS中,中間件主要是指封裝http請求細節處理的方法

例如在express、koa等web框架中,中間件的本質為一個回調函數,參數包含請求對象、響應對象和執行下一個中間件的函數

在這些中間件函數中,我們可以執行業務邏輯代碼,修改請求和響應對象、返回響應數據等操作

二、封裝

koa是基于NodeJS當前比較流行的web框架,本身支持的功能并不多,功能都可以通過中間件拓展實現。通過添加不同的中間件,實現不同的需求,從而構建一個 Koa 應用

Koa 中間件采用的是洋蔥圈模型,每次執行下一個中間件傳入兩個參數:

ctx :封裝了request 和 response 的變量

next :進入下一個要執行的中間件的函數

下面就針對koa進行中間件的封裝:

Koa的中間件就是函數,可以是async 函數,或是普通函數

  1. // async 函數 
  2. app.use(async (ctx, next) => { 
  3.   const start = Date.now(); 
  4.   await next(); 
  5.   const ms = Date.now() - start; 
  6.   console.log(`${ctx.method} ${ctx.url} - ${ms}ms`); 
  7. }); 
  8.  
  9. // 普通函數 
  10. app.use((ctx, next) => { 
  11.   const start = Date.now(); 
  12.   return next().then(() => { 
  13.     const ms = Date.now() - start; 
  14.     console.log(`${ctx.method} ${ctx.url} - ${ms}ms`); 
  15.   }); 
  16. }); 

下面則通過中間件封裝http請求過程中幾個常用的功能:

token校驗

  1. module.exports = (options) => async (ctx, next) { 
  2.   try { 
  3.     // 獲取 token 
  4.     const token = ctx.header.authorization 
  5.     if (token) { 
  6.       try { 
  7.           // verify 函數驗證 token,并獲取用戶相關信息 
  8.           await verify(token) 
  9.       } catch (err) { 
  10.         console.log(err) 
  11.       } 
  12.     } 
  13.     // 進入下一個中間件 
  14.     await next() 
  15.   } catch (err) { 
  16.     console.log(err) 
  17.   } 

日志模塊

  1. const fs = require('fs'
  2. module.exports = (options) => async (ctx, next) => { 
  3.   const startTime = Date.now() 
  4.   const requestTime = new Date() 
  5.   await next() 
  6.   const ms = Date.now() - startTime; 
  7.   let logout = `${ctx.request.ip} -- ${requestTime} -- ${ctx.method} -- ${ctx.url} -- ${ms}ms`; 
  8.   // 輸出日志文件 
  9.   fs.appendFileSync('./log.txt', logout + '\n'

Koa存在很多第三方的中間件,如koa-bodyparser、koa-static等

下面再來看看它們的大體的簡單實現:

koa-bodyparser

koa-bodyparser 中間件是將我們的 post 請求和表單提交的查詢字符串轉換成對象,并掛在 ctx.request.body 上,方便我們在其他中間件或接口處取值

  1. // 文件:my-koa-bodyparser.js 
  2. const querystring = require("querystring"); 
  3.  
  4. module.exports = function bodyParser() { 
  5.     return async (ctx, next) => { 
  6.         await new Promise((resolve, reject) => { 
  7.             // 存儲數據的數組 
  8.             let dataArr = []; 
  9.  
  10.             // 接收數據 
  11.             ctx.req.on("data", data => dataArr.push(data)); 
  12.  
  13.             // 整合數據并使用 Promise 成功 
  14.             ctx.req.on("end", () => { 
  15.                 // 獲取請求數據的類型 json 或表單 
  16.                 let contentType = ctx.get("Content-Type"); 
  17.  
  18.                 // 獲取數據 Buffer 格式 
  19.                 let data = Buffer.concat(dataArr).toString(); 
  20.  
  21.                 if (contentType === "application/x-www-form-urlencoded") { 
  22.                     // 如果是表單提交,則將查詢字符串轉換成對象賦值給 ctx.request.body 
  23.                     ctx.request.body = querystring.parse(data); 
  24.                 } else if (contentType === "applaction/json") { 
  25.                     // 如果是 json,則將字符串格式的對象轉換成對象賦值給 ctx.request.body 
  26.                     ctx.request.body = JSON.parse(data); 
  27.                 } 
  28.  
  29.                 // 執行成功的回調 
  30.                 resolve(); 
  31.             }); 
  32.         }); 
  33.  
  34.         // 繼續向下執行 
  35.         await next(); 
  36.     }; 
  37. }; 

koa-static

koa-static 中間件的作用是在服務器接到請求時,幫我們處理靜態文件

  1. const fs = require("fs"); 
  2. const path = require("path"); 
  3. const mime = require("mime"); 
  4. const { promisify } = require("util"); 
  5.  
  6. // 將 stat 和 access 轉換成 Promise 
  7. const stat = promisify(fs.stat); 
  8. const access = promisify(fs.access) 
  9.  
  10. module.exports = function (dir) { 
  11.     return async (ctx, next) => { 
  12.         // 將訪問的路由處理成絕對路徑,這里要使用 join 因為有可能是 / 
  13.         let realPath = path.join(dir, ctx.path); 
  14.  
  15.         try { 
  16.             // 獲取 stat 對象 
  17.             let statObj = await stat(realPath); 
  18.  
  19.             // 如果是文件,則設置文件類型并直接響應內容,否則當作文件夾尋找 index.html 
  20.             if (statObj.isFile()) { 
  21.                 ctx.set("Content-Type", `${mime.getType()};charset=utf8`); 
  22.                 ctx.body = fs.createReadStream(realPath); 
  23.             } else { 
  24.                 let filename = path.join(realPath, "index.html"); 
  25.  
  26.                 // 如果不存在該文件則執行 catch 中的 next 交給其他中間件處理 
  27.                 await access(filename); 
  28.  
  29.                 // 存在設置文件類型并響應內容 
  30.                 ctx.set("Content-Type""text/html;charset=utf8"); 
  31.                 ctx.body = fs.createReadStream(filename); 
  32.             } 
  33.         } catch (e) { 
  34.             await next(); 
  35.         } 
  36.     } 

三、總結

在實現中間件時候,單個中間件應該足夠簡單,職責單一,中間件的代碼編寫應該高效,必要的時候通過緩存重復獲取數據

koa本身比較簡潔,但是通過中間件的機制能夠實現各種所需要的功能,使得web應用具備良好的可拓展性和組合性

通過將公共邏輯的處理編寫在中間件中,可以不用在每一個接口回調中做相同的代碼編寫,減少了冗雜代碼,過程就如裝飾者模式

參考文獻

https://segmentfault.com/a/1190000017897279

https://www.jianshu.com/p/81b6ebc0dd85

https://baike.baidu.com/item/%E4%B8%AD%E9%97%B4%E4%BB%B6

 

責任編輯:武曉燕 來源: JS每日一題
相關推薦

2021-07-19 07:55:24

Redux中間件原理

2011-05-24 15:10:48

2021-02-11 08:21:02

中間件開發CRUD

2022-11-18 07:54:02

Go中間件項目

2016-11-11 21:00:46

中間件

2018-02-01 10:19:22

中間件服務器系統

2018-07-29 12:27:30

云中間件云計算API

2020-08-19 08:39:05

中間件前端設計模式

2020-11-02 08:51:57

中間件和洋蔥模型

2012-11-30 10:21:46

移動中間件

2023-06-29 10:10:06

Rocket MQ消息中間件

2023-10-24 07:50:18

消息中間件MQ

2009-06-16 15:55:06

JBoss企業中間件

2020-11-06 09:24:09

node

2013-03-13 10:37:22

中間件Windows

2018-05-02 16:23:24

中間件RPC容器

2015-02-07 21:52:45

PaaS中間件

2018-05-08 16:33:31

中間件RPC企業

2019-09-29 11:04:22

MySQL數據庫Atlas

2020-02-10 15:30:51

數據庫MySQLDAL
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩一区二区福利视频 | 国产欧美精品 | 日韩欧美精品 | 中文字幕 在线观看 | 国产免费又黄又爽又刺激蜜月al | 国产亚洲一区二区三区在线 | 神马久久久久久久久久 | 一级黄色毛片a | 一区二区不卡高清 | 国产a区| 99久久免费精品视频 | 国产精品视频中文字幕 | 激情91| 精品国产成人 | 日韩激情视频一区 | 亚洲成人播放器 | 久久99久久99精品免视看婷婷 | 男女在线免费观看 | 亚洲精品精品 | 久久这里只有精品首页 | 国产免费看 | 97精品国产97久久久久久免费 | 国产精品国产成人国产三级 | 久久久久亚洲 | 久久精品综合 | 一区欧美| 欧美久久一级特黄毛片 | 久久久久国产精品www | 狠狠干网站 | 国产在线资源 | 亚洲精品久久久久久久不卡四虎 | 亚洲精品视频一区 | 久久久久久久久久久久一区二区 | 日韩一二区| 成人在线精品视频 | 亚洲免费视频在线观看 | 国产精品久久久久久久久 | 精品在线免费看 | 男人的天堂在线视频 | 欧美综合一区二区 | 国产精品精品视频一区二区三区 |