Express Middleware 的简易实现

本文最后更新于:2025年1月29日 凌晨

原文地址:Simple implementation principle of Express Middleware

简而言之,express 中间件,就是在服务器端处理请求对象响应对象的函数。

遵循一个先注册,先执行的原则,通过调用next()函数,把执行权交给下一个函数。

核心代码:

1
2
3
4
5
6
7
const next = () => {
const stack = stacks.shift();
if(stack) {
stack(req, res, next);
}
}
next();

express 简易实现的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
const http = require('http')
const slice = Array.prototype.slice

class Express {
constructor() {
this.router = {
all: [], // Match all middleware functions
get: [],
post: []
}
}

/**
* Integrate middleware here
* @param {string} path
* @returns {object}
*/
middlewareHandler(path) {
const info = {}
if (typeof path === 'string') {
// by use()、get()、post()、pass into <path> and <handler>
// 如果包含路劲参数,那么第二个参数开始才是中间件函数
info.path = path
info.stack = slice.call(arguments, 1) // Middleware array
} else {
// 只传进去中间件函数,那么全部是handler.
info.path = '/'
info.stack = slice.call(arguments, 0)
}

return info
}

use() {
const allStack = this.middlewareHandler(...arguments)
this.router.all.push(allStack)
}

get() {
const getStack = this.middlewareHandler(...arguments)
this.router.get.push(getStack)
}

post() {
const postStack = this.middlewareHandler(...arguments)
this.router.post.push(postStack)
}
// 通过按照 方法 分类,建立 路径 到 处理函数 的映射
/**
*
* @param {string} method
* @param {string} url
* @returns {Array}
*/
accordStack(method, url) {
let stacks = []
stacks = stacks.concat(this.router.all)
stacks = stacks.concat(this.router[method])
return stacks
.filter(stack => {
return url.indexOf(stack.path) !== -1
}).map(item => item.stack[0]) // 这里有点问题,不应该只传进去第一个handler.
}

handler(req, res, stacks) {
// Function expression
const next = () => {
const stack = stacks.shift()
if(stack) {
stack(req, res, next)
}
}
next()
}

callback() {
return (req, res) => {
res.json = data => {
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(data))
}

// Get the request method and url, and filter the middleware functions
const {method, url} = req
const stacks = this.accordStack(method.toLowerCase(), url)
this.handler(req, res, stacks)
}
}

listen(...args) {
const server = http.createServer(this.callback())
server.listen(...args)
}
}

// Factory mode, export an instance object
module.exports = () => {
return new Express()
}

Express Middleware 的简易实现
https://hercules11.github.io/blog/2022/01/09/express-middleware简易实现/
作者
wxc
发布于
2022年1月9日
许可协议