浅谈express 中间件机制及实现原理
发布时间 - 2026-01-11 03:02:48 点击率:次简介

中间件机制可以让我们在一个给定的流程中添加一个处理步骤,从而对这个流程的输入或者输出产生影响,或者产生一些中作用、状态,或者拦截这个流程。中间件机制和tomcat的过滤器类似,这两者都属于责任链模式的具体实现。
express 中间件使用案例
let express = require('express')
let app = express()
//解析request 的body
app.use(bodyParser.json())
//解析 cookie
app.use(cookieParser())
//拦截
app.get('/hello', function (req, res) {
res.send('Hello World!');
});
模拟中间件机制并且模拟实现解析request的中间件
首先模拟一个request
request = { //模拟的request
requestLine: 'POST /iven_ HTTP/1.1',
headers: 'Host:www.baidu.com\r\nCookie:BAIDUID=E063E9B2690116090FE24E01ACDDF4AD:FG=1;BD_HOME=0',
requestBody: 'key1=value1&key2=value2&key3=value3',
}
一个http请求分为请求行、请求头、和请求体,这三者之间通过\r\n\r\n即一个空行来分割,这里假设已经将这三者分开,requestLine(请求行)中有方法类型,请求url,http版本号,这三者通过空格来区分,headers(请求头)中的各部分通过\r\n来分割,requestBody(请求体)中通过 & 来区分参数
模拟中间件机制
约定 中间件一定是一个函数并且接受 request, response, next三个参数
function App() {
if (!(this instanceof App))
return new App();
this.init();
}
App.prototype = {
constructor: App,
init: function() {
this.request = { //模拟的request
requestLine: 'POST /iven_ HTTP/1.1',
headers: 'Host:www.baidu.com\r\nCookie:BAIDUID=E063E9B2690116090FE24E01ACDDF4AD:FG=1;BD_HOME=0',
requestBody: 'key1=value1&key2=value2&key3=value3',
};
this.response = {}; //模拟的response
this.chain = []; //存放中间件的一个数组
this.index = 0; //当前执行的中间件在chain中的位置
},
use: function(handle) { //这里默认 handle 是函数,并且这里不做判断
this.chain.push(handle);
},
next: function() { //当调用next时执行index所指向的中间件
if (this.index >= this.chain.length)
return;
let middleware = this.chain[this.index];
this.index++;
middleware(this.request, this.response, this.next.bind(this));
},
}
对 request 处理的中间件
function lineParser(req, res, next) {
let items = req.requestLine.split(' ');
req.methond = items[0];
req.url = items[1];
req.version = items[2];
next(); //执行下一个中间件
}
function headersParser(req, res, next) {
let items = req.headers.split('\r\n');
let header = {}
for(let i in items) {
let item = items[i].split(':');
let key = item[0];
let value = item[1];
header[key] = value;
}
req.header = header;
next(); //执行下一个中间件
}
function bodyParser(req, res, next) {
let bodyStr = req.requestBody;
let body = {};
let items = bodyStr.split('&');
for(let i in items) {
let item = items[i].split('=');
let key = item[0];
let value = item[1];
body[key] = value;
}
req.body = body;
next(); //执行下一个中间件
}
function middleware3(req, res, next) {
console.log('url: '+req.url);
console.log('methond: '+req.methond);
console.log('version: '+req.version);
console.log(req.body);
console.log(req.header);
next(); //执行下一个中间件
}
测试代码
let app = App(); app.use(lineParser); app.use(headersParser); app.use(bodyParser); app.use(middleware3); app.next();
整体代码
function App() {
if (!(this instanceof App))
return new App();
this.init();
}
App.prototype = {
constructor: App,
init: function() {
this.request = { //模拟的request
requestLine: 'POST /iven_ HTTP/1.1',
headers: 'Host:www.baidu.com\r\nCookie:BAIDUID=E063E9B2690116090FE24E01ACDDF4AD:FG=1;BD_HOME=0',
requestBody: 'key1=value1&key2=value2&key3=value3',
};
this.response = {}; //模拟的response
this.chain = []; //存放中间件的一个数组
this.index = 0; //当前执行的中间件在chain中的位置
},
use: function(handle) { //这里默认 handle 是函数,并且这里不做判断
this.chain.push(handle);
},
next: function() { //当调用next时执行index所指向的中间件
if (this.index >= this.chain.length)
return;
let middleware = this.chain[this.index];
this.index++;
middleware(this.request, this.response, this.next.bind(this));
},
}
function lineParser(req, res, next) {
let items = req.requestLine.split(' ');
req.methond = items[0];
req.url = items[1];
req.version = items[2];
next(); //执行下一个中间件
}
function headersParser(req, res, next) {
let items = req.headers.split('\r\n');
let header = {}
for(let i in items) {
let item = items[i].split(':');
let key = item[0];
let value = item[1];
header[key] = value;
}
req.header = header;
next(); //执行下一个中间件
}
function bodyParser(req, res, next) {
let bodyStr = req.requestBody;
let body = {};
let items = bodyStr.split('&');
for(let i in items) {
let item = items[i].split('=');
let key = item[0];
let value = item[1];
body[key] = value;
}
req.body = body;
next(); //执行下一个中间件
}
function middleware3(req, res, next) {
console.log('url: '+req.url);
console.log('methond: '+req.methond);
console.log('version: '+req.version);
console.log(req.body);
console.log(req.header);
next(); //执行下一个中间件
}
let app = App();
app.use(lineParser);
app.use(headersParser);
app.use(bodyParser);
app.use(middleware3);
app.next();
运行结果
将以上整体代码运行后将打印以下信息
url: /iven_
methond: POST
version: HTTP/1.1
{key1: "value1", key2: "value2", key3: "value3"}
{Host: "www.baidu.com", Cookie: "BAIDUID=E063E9B2690116090FE24E01ACDDF4AD"}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# express
# 中间件
# 中间件原理
# 浅谈express.js框架中间件(middleware)
# express.js中间件说明详解
# express文件上传中间件Multer详解
# express的中间件cookieParser详解
# express的中间件bodyParser详解
# JavaScript 实现类似Express的中间件系统(实例详解)
# 下一
# 这三
# 不做
# 是一个
# 让我们
# 中有
# 后将
# 而对
# 大家多多
# 这两者
# 各部分
# tomcat
# headers
# POST
# requestLine
# HTTP
# br
# E063E9B2690116090FE24E01ACDDF4AD
# BAIDUID
# BD_HOME
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251811 】
【
AI营销90571 】
相关推荐:
微信小程序 配置文件详细介绍
如何解决hover在ie6中的兼容性问题
Swift中循环语句中的转移语句 break 和 continue
Laravel如何配置Horizon来管理队列?(安装和使用)
黑客如何通过漏洞一步步攻陷网站服务器?
如何用PHP快速搭建CMS系统?
制作旅游网站html,怎样注册旅游网站?
如何挑选优质建站一级代理提升网站排名?
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤
JavaScript数据类型有哪些_如何准确判断一个变量的类型
Laravel如何实现用户密码重置功能?(完整流程代码)
C语言设计一个闪闪的圣诞树
详解Android中Activity的四大启动模式实验简述
Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作
Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】
焦点电影公司作品,电影焦点结局是什么?
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
php 三元运算符实例详细介绍
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
Laravel怎么在Blade中安全地输出原始HTML内容
Python企业级消息系统教程_KafkaRabbitMQ高并发应用
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
高端建站三要素:定制模板、企业官网与响应式设计优化
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
jQuery validate插件功能与用法详解
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
Laravel怎么调用外部API_Laravel Http Client客户端使用
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
简历在线制作网站免费版,如何创建个人简历?
打开php文件提示内存不足_怎么调整php内存限制【解决方案】
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
简历没回改:利用AI润色让你的文字更专业
在Oracle关闭情况下如何修改spfile的参数
使用Dockerfile构建java web环境
微信小程序制作网站有哪些,微信小程序需要做网站吗?
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
如何挑选最适合建站的高性能VPS主机?

