实用中间件模式25例
1. 基础增强模式
请求属性扩展
function extendRequest() {return (req, res, next) => {req.getClientLanguage = () => {return req.headers['accept-language']?.split(',')[0] || 'en';};next();};
}
响应时间头
function responseTime() {return (req, res, next) => {const start = Date.now();res.on('finish', () => {res.setHeader('X-Response-Time', `${Date.now() - start}ms`);});next();};
}
2. 安全相关中间件
CSRF防护
function csrfProtection() {return (req, res, next) => {if (['POST', 'PUT', 'DELETE'].includes(req.method)) {const csrfToken = req.headers['x-csrf-token'];if (!csrfToken || csrfToken !== req.session.csrfToken) {return res.status(403).send('Invalid CSRF token');}}next();};
}
CORS配置
function cors(options = {}) {return (req, res, next) => {res.setHeader('Access-Control-Allow-Origin', options.origin || '*');res.setHeader('Access-Control-Allow-Methods', options.methods || 'GET,POST,PUT,DELETE');res.setHeader('Access-Control-Allow-Headers', options.headers || 'Content-Type,Authorization');options.credentials && res.setHeader('Access-Control-Allow-Credentials', 'true');req.method === 'OPTIONS' ? res.sendStatus(200) : next();};
}
3. 数据转换中间件
请求体格式化
function formatBody() {return (req, res, next) => {if (req.body) {// 去除字符串两端的空格Object.keys(req.body).forEach(key => {if (typeof req.body[key] === 'string') {req.body[key] = req.body[key].trim();}});}next();};
}
响应数据包装
function wrapResponse() {return (req, res, next) => {const originalSend = res.send;res.send = function(data) {const wrapped = {status: 'success',data: data,timestamp: new Date().toISOString()};originalSend.call(this, wrapped);};next();};
}
高级组合技巧
1. 中间件条件执行
function when(predicate, middleware) {return (req, res, next) => {predicate(req) ? middleware(req, res, next) : next();};
}// 使用示例
app.use(when(req => req.path.startsWith('/api'),helmet()
));
2. 中间件并行执行
function parallel(middlewares) {return (req, res, next) => {let completed = 0;const done = () => ++completed === middlewares.length && next();middlewares.forEach(mw => {mw(req, res, done);});};
}// 使用示例
app.use(parallel([requestLogger,responseTime,bodyParser.json()
]));
3. 中间件管道
function pipe(...middlewares) {return (req, res, next) => {const run = i => i < middlewares.length ? middlewares[i](req, res, () => run(i + 1)): next();run(0);};
}
性能优化中间件
1. 缓存中间件
function cache(duration) {const cacheStore = new Map();return (req, res, next) => {const key = req.originalUrl;const cached = cacheStore.get(key);if (cached && cached.expiry > Date.now()) {return res.send(cached.data);}const originalSend = res.send;res.send = function(body) {cacheStore.set(key, {data: body,expiry: Date.now() + duration});originalSend.call(this, body);};next();};
}
2. 压缩中间件
const zlib = require('zlib');function compression() {return (req, res, next) => {const acceptEncoding = req.headers['accept-encoding'] || '';const originalSend = res.send;res.send = function(body) {if (acceptEncoding.includes('gzip')) {res.setHeader('Content-Encoding', 'gzip');zlib.gzip(Buffer.from(body), (err, result) => {if (err) return originalSend.call(this, body);originalSend.call(this, result);});} else {originalSend.call(this, body);}};next();};
}
调试与错误处理
1. 调试中间件
function debugMiddleware() {return (req, res, next) => {console.log('--- Request Start ---');console.log(`Method: ${req.method}`);console.log(`Path: ${req.path}`);console.log('Headers:', req.headers);console.log('Query:', req.query);console.log('Body:', req.body);const originalSend = res.send;res.send = function(body) {console.log('--- Response ---');console.log(`Status: ${res.statusCode}`);console.log('Body:', body);originalSend.call(this, body);};next();};
}
2. 错误处理增强
function errorHandler() {return (err, req, res, next) => {console.error(err.stack);const status = err.status || 500;const message = status === 500 ? 'Internal Server Error' : err.message;res.status(status).json({error: {message: message,code: err.code,timestamp: new Date().toISOString(),path: req.path}});};
}
实战项目推荐
- API网关:组合各种验证、限流、日志中间件
- 文件处理管道:创建文件上传处理链
- A/B测试框架:基于中间件的流量分配
- 多租户系统:通过中间件识别租户
下节将带来以上更加详尽的项目实践。
Express中间件(Middleware)详解:从零开始掌握(4)-CSDN博客