https://eggjs.org/zh-cn/basics/middleware.html#mobileAside
Middleware中间件文档 https://eggjs.github.io/zh/guide/middleware.html
eggjs中间件的目录 src/app/middleware
什么是中间件
在NodeJS中,中间件主要是指封装所有Http 请求细节处理的方法
每个中间件都会执行2次,
一次 Http 请求通常包含很多工作,如
- 记录日志、ip过滤、查询字符串、请求体解析、
- Cookie处理、权限验证、
- 参数验证、
- 异常处理等
但对于Web应用而言,并不希望接触到这么多细节性的处理,
- 因此引入中间件来简化和隔离这些基础设施与业务逻辑之间的细节,
- 让开发者能够关注在业务的开发上,以达到提升开发效率的目的
自定义 koa中间件实现用户认证授权
koa-jwt中间件实现用户认证和鉴权
config.middleware
中间件可以帮我们解决一些不必要放在路由中的一些逻辑处理
在匹配到路由 之前 或者 之后做的一些事情
- next()
- 每次路由变化都会触发 中间件
- 因为 egg 是基于 koa的 所以koa得洋葱模型也被 egg所采用
中间件必须返回 next() 否则不会往下执行
await next();
中间件的名字要和 ap/middleware下文件的名字保持一致
config.middleware = [ 'httpLog', 'httpError', 'forbiddenIP' ];
洋葱圈模型
洋葱圈模型 https://eggjs.org/zh-cn/intro/egg-and-koa.html#midlleware
m1 start
m2 start
…
m2 end
m1 end
config.middleware中,注册的中间件是有执行的先后顺序的
中间件执行,按照洋葱圈模型的执行顺序,所以 中间件必须返回 next() 否则不会往下执行
await next();
config.middleware = ['m1', 'm2'];
中间件模板
options 是给 中间件传来的参数
app 是当前的应用实例
'use strict';
module.exports = (options, app) => {
return async (ctx, next) => {
console.log('options', options, app);
await next();
};
};
config.default.js
在 src/config/config.default.js 中注册中间件
在路由匹配的时候 执行了下 并且参数也正确传入进去了
// 配置中间件 文件名字要对应起来
config.middleware = ['httpLog'];
// 给中间件传参
config.httpLog = {
type: 'all'
}
options参数
httpLog中间件
'use strict';
const dayjs = require('moment');
const fs = require('fs');
/**
* 拦截 http请求,将请求输入到 /logs/http/httpLog.log文件中
* @param options
* @param app
* @returns {(function(*, *): Promise<void>)|*}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (options, app) => {
return async (ctx, next) => {
const start = Date.now();
const startedAt = dayjs().format('YYYY-MM-DD HH:mm:ss');
const {
method, url, body,
} = ctx.request;
// app.baseDir = /Users/lulongwen/Sites/珑文汽修/egg-server
// console.log('options', options, app.baseDir);
await next();
const log = {
method, url, body,
startedAt,
endAt: dayjs().format('YYYY-MM-DD HH:mm:ss'),
time: Date.now() - start,
};
const data = `${dayjs().format('YYYY-MM-DD HH:mm:ss')} [httpLog] ${JSON.stringify(log)} \r\n`;
const output = `${ctx.app.baseDir}/logs/http/httpLog.log`;
fs.appendFileSync(output, data);
};
};