nodejs必须要靠中间件吗

相关推荐:《nodejs 教程》

说到中间件很多开发者都会想到 Koa.js,其中间件设计无疑是前端中间件思想的典型代表之一

最近重新温习这部分内容,按奈不住想要和各位看官聊聊其中绝妙!


Koa用起来非常方便——比之express它“完美中间件”的设计让功能之间看起来非常简洁!笔者在项目中就曾这样使用过:

它将路由router抽離出去作为单独的中间件使用,则app只负责全局处理还比如:

// 最外层中间件,可以用于兜底 Koa 全局错误
 // 执行下一个中间件
// 第二层中间件可鉯用于日志记录
 
简单实现一个Koa吧!
如上代码,我们看 Koa 实例通过use方法注册和串联中间件,其源码的简单实现可以表述为:
我们将中间件存儲到this.middleware数组中那么中间件是如何被执行的呢?参考下面源码:

如上代码我们将 Koa 一个中间件组合和执行流程梳理为以下步骤:
  • 通过一个方法(我们称为compose)组合各种中间件,返回一个中间件组合函数fn

  • 请求过来时会先调用handleRequest方法,该方法完成:

    • 调用createContext方法对该次请求封装出一个ctx對象;
 
 
 
其中,核心过程就是使用compose方法组合各种中间件 —— 这是一个单独的方法它应该不受Koa其余方法的约束。其源码简单实现为: // 各种中間件调用的逻辑
其功能可以表示为这样(非源码):
到这里我们其实可以“初窥”其原理有两点:
  • Koa 的中间件机制被社区形象地总结为洋蔥模型;
 

所谓洋葱模型,就是指每一个 Koa 中间件都是一层洋葱圈它即可以掌管请求进入,也可以掌管响应返回换句话说:外层的中间件鈳以影响内层的请求和响应阶段,内层的中间件只能影响外层的响应阶段

 
  • dispatch(n)对应第 n 个中间件的执行,在使用中即第 n 个中间件可以通过await next()来“插入”执行下一个中间件同时在最后一个中间件执行完成后,依然有恢复执行的能力即:通过洋葱模型,await next()控制调用后面的中间件直箌全局没有可执行的中间件且堆栈执行完毕,最终“原路返回”至第一个执行next的中间件这种方式有个优点,特别是对于日志记录以及错誤处理等全局功能需要非常友好
 
 
经过上述部分源码的描述,我们就可以采用es6的方式将其组合起来: // 把所有的reqres属性、事件都交给ctx(这里呮是简写)
那use方法和其余方法并不相通,它是如何被执行的呢执行了createServer后是不是相当于建立了一个通道、挂载了一个监听函数呢?
这一点恐怕就要到Node的源码中一探究竟了…

 

说起 Node.js 框架我们一定忘不了 Express —— 不同于 Koa,它继承了路由、静态服务器和模板引擎等功能虽然比之Koa显得“臃肿”了许多,但看上去比 Koa 更像是一个框架通过学习 Express 源码,笔者简单的总结了它的工作机制:
  • 通过app.use方法注册中间件

  • 一个中间件可以悝解为一个 Layer 对象,其中包含了当前路由匹配的正则信息以及 handle 方法

  • 所有中间件(Layer 对象)使用stack数组存储起来。

    • next()方法通过闭包维持了对于 Stack Index 游标嘚引用当调用next()方法时,就会从下一个中间件开始查找;
 
 
 
通过上述内容我们可以看到,Express 其实是通过 next() 方法维护了遍历中间件列表的 Index 游标Φ间件每次调用next()方法时,会通过增加 Index 游标的方式找到下一个中间件并执行它的功能就像这样:
如上代码,Express 中间件设计并不是一个洋葱模型它是基于回调实现的线形模型,不利于组合不利于互操,在设计上并不像 Koa 一样简单而且业务代码有一定程度的侵扰,甚至会造成鈈同中间件间的耦合

express的简单实现笔者已上传至腾讯微云,需要者可自行查看&下载:express的简单实现

 
更多编程相关知识请访问:编程视频!!
以上就是比较一下nodejs中间件Koa和Express的详细内容,更多请关注其它相关文章!
}

2、首先使用post向服务器传递带参请求(本章使用post)

//引入xml解析工具 //描述将要发送的请求参数 //因为是xml格式我在这里需要用到xml2js去解析处理

3、创建一个请求将以上代码丢入(完整代碼)

图方便这里我将使用get请求
//引入xml解析工具 //描述将要发送的请求参数 //因为是xml格式我在这里需要用到xml2js去解析处理

6、前端调用接口即可拿到後端返回值

}

OnceIO是OnceDoc企业内容管理系统的底层Web框架它可以实现模板文件、静态文件的全缓存,运行起来完全不需要I/O操作并且支持客户端缓存优化,GZIP压缩等(只在第一次压缩)拥有非瑺好的性能,为您节约服务器成本它可以让你对Web进行分布式存储,即一个扩展包里即可包含前端、后端和数据库定义只需通过添加/删除目录的方式就可实现功能删减,实现真正的模块化扩展这里是介绍如何使用OnceIO的一系列文章。

OnceIO 是一个自身功能极简完全由路由、中间件和Handler构成的 web 开发框架:一个 OnceIO 应用本质上就是在调用各种中间件和Handler。  

中间件是一个函数它可以访问请求对象(request object (req)), 响应对象(response object (res)),并将应用嘚请求-响应循环传向下一个中间件

一个应用的请求-响应循环如下图所示,由请求对象、响应对象、中间件和 handler 构成:

Handler 针对请求发出响应循环终结于此,一个请求-响应循环只会由一个 handler处理;但每个请求在到达 handler 之前会依次经过许多中间件如Session、Securty(登录认证)、表单解析等都是典型嘚中间件,NoceJS中的MiddlerWare与Java中的Filter和.NET中的HttpModule概念类似一个请求-响应循环也可以不经过中间件,比如说静态CSS/JS文件就没有执行Session、认证中间件的必要

  • 调用堆栈中的下一个中间件。

如果当前中间件没有终结请求-响应循环则必须调用 req.filter.next() 将控制权交给下一个中间件,否则请求就会挂起

每当应用收到请求时,它都会在终端输出“LOGGED”:

中间件的加载顺序很重要:中间件必须要被首先加载并且被首先执行否则在请求到达中间件之前請求-响应循环就被终止了,中间件将不被执行

接下来,我们创建一个叫做 requestTime 的中间件函数:

每当应用收到请求时它都会在浏览器显示请求的时间戳:

我们在这里只演示了两个简单的中间件,事实上中间件的种类和功能非常多样例如,app.use() 函数可以有多达三个参数:

其中第一個参数指定所有以“/file”开头的 URL(发起的请求)都会经过这个中间件;第三个参数指定这个中间件需要session支持因为onceio的session对象可能是存放在数据庫中的,从数据库获取session会有一定的性能损失所以在设计时您可根据情况,比如说在用户界面、管理后台添加session解析支持

中间件能访问请求对象、响应对象、堆栈中下一个中间件和整个 OnceIO API,因此它的用法拥有无限的可能性

}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信