浅谈express 中间件机制及实现原理
程序员文章站
2022-05-14 19:08:32
简介
中间件机制可以让我们在一个给定的流程中添加一个处理步骤,从而对这个流程的输入或者输出产生影响,或者产生一些中作用、状态,或者拦截这个流程。中间件机制和tomca...
简介
中间件机制可以让我们在一个给定的流程中添加一个处理步骤,从而对这个流程的输入或者输出产生影响,或者产生一些中作用、状态,或者拦截这个流程。中间件机制和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"}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: JavaScript基础进阶之数组方法总结(推荐)
下一篇: JavaScript实现旋转轮播图