[eggjs/egg]egg框架中使用中间件无法获得ctx.request.body对象

2025-11-04 804 views
8

框架中加载的中间件无法获得ctx.request.body对象,但是在项目中通过config配置就可以获得,请问这是使用问题,还是本身就存在BUG?

代码仓库:https://github.com/ddzyan/middleware-ddz

回答

4

你的问题是框架中加载的中间件无法获得ctx.request.body对象,但是你提交的代码仓库完全没有关于middleware的使用代码,检查一下是不是提交错了? 另外根据我这边实际使用情况,中间件里面是可以拿到ctx传递的参数的,感觉是你代码写错了,可以看看官方文档的写法中间件写法

8

测试仓库似乎没有 ctx.request.body 的逻辑?

7

测试仓库似乎没有 ctx.request.body 的逻辑?

我提交的代码加载了一个外部框架,中间件写在外部框架里。 package.json

{
"egg": {
    "declarations": true,
    "framework": "middleware-egg-frame-ddz"
  }
}

这是外部框架的仓库 https://github.com/ddzyan/middleware-egg-frame-ddz

8

你的问题是框架中加载的中间件无法获得ctx.request.body对象,但是你提交的代码仓库完全没有关于middleware的使用代码,检查一下是不是提交错了? 另外根据我这边实际使用情况,中间件里面是可以拿到ctx传递的参数的,感觉是你代码写错了,可以看看官方文档的写法中间件写法

我的问题是在框架中使用中间件,所以项目里没有中间件是符合实际情况的,中间件在引用的框架中 package.json

{
"egg": {
    "declarations": true,
    "framework": "middleware-egg-frame-ddz"
  }
}

框架地址:https://github.com/ddzyan/middleware-egg-frame-ddz

0

把你在框架中使用的 middleware 拿不到 ctx.request.body 的代码贴一下?

2

把你在框架中使用的 middleware 拿不到 ctx.request.body 的代码贴一下?

'use strict';
function formatRequest(ctx) {
  const {
    request: { method, traceid, body, query },
  } = ctx;

  return `begin || requestData:${method === 'GET' ? query : JSON.stringify(
    body
  )} || traceid:${traceid}\n`;
}

function formatResponse(ctx) {
  const {
    status,
    body,
    request: { traceid },
  } = ctx;

  const data = {
    status,
    body,
  };

  return `end || responseBody:${JSON.stringify(data)} || traceid:${traceid}\n`;
}

module.exports = (option, app) => {
  return async (ctx, next) => {
    try {
      ctx.request.startTime = new Date();
      ctx.logger.info(formatRequest(ctx));
      await next();
      if (ctx.status === 200) {
        ctx.body = {
          code: '1000',
          msg: 'SUCCESS',
          data: ctx.body,
        };
      } else {
        ctx.body = '没有找到内容 - 404';
      }
    } catch (error) {
      ctx.status = 200;
      ctx.body = {
        data: {},
        sign: '',
      };
    } finally {
      ctx.logger.info(formatResponse(ctx));
    }
  };
};
7

我试了下确实如此,看起来是 framework 你的中间件 requestHandler 加载的时机比 bodyParser 更早造成的,也就是触发到你的中间件时根本还没对 request body 进行解析。

其实你在 requestHandler 里加一行 console.log(ctx.app.middleware); 也可以看到中间件的顺序:

[
  [AsyncFunction] { _name: 'requestHandler' },
  [AsyncFunction: meta] { _name: 'meta' },
  [Function: siteFile] { _name: 'siteFile' },
  [AsyncFunction: notfound] { _name: 'notfound' },
  [Function] { _name: 'static' },
  [AsyncFunction: bodyParser] { _name: 'bodyParser' },
  [Function: overrideMethod] { _name: 'overrideMethod' },
  [AsyncFunction: session] { _name: 'session' },
  [Function] { _name: 'securities' },
  [Function: i18n] { _name: 'i18n' },
  [AsyncFunction] { _name: 'eggLoaderTrace' },
  [Function: dispatch] {
    router: EggRouter {
      opts: [Object],
      methods: [Array],
      params: {},
      stack: [Array],
      app: [Object],
      head: [Function],
      options: [Function],
      get: [Function],
      put: [Function],
      patch: [Function],
      post: [Function],
      delete: [Function],
      all: [Function]
    }
  }
]
4

https://github.com/ddzyan/middleware-egg-frame-ddz/blob/master/app.js#L4

你这里手动把你的中间件放到所有中间件之前了,当然会有这个问题,调整下中间件的顺序吧,要么就纯计时不要操作 request.body

5

https://github.com/ddzyan/middleware-egg-frame-ddz/blob/master/app.js#L4

你这里手动把你的中间件放到所有中间件之前了,当然会有这个问题,调整下中间件的顺序吧,要么就纯计时不要操作 request.body

我也碰到了同样的问题,ctx.request.body取不到值,我是在插件里面使用中间件的 以下是我打印出来的中间件加载顺序

[ { [Function: fn] _name: 'transformmiddlewareWrapper' },
  { [AsyncFunction: search] _name: 'search' },
  { [AsyncFunction: meta] _name: 'meta' },
  { [Function: siteFile] _name: 'siteFile' },
  { [AsyncFunction: notfound] _name: 'notfound' },
  { [Function] _name: 'static' },
  { [AsyncFunction: bodyParser] _name: 'bodyParser' },
  { [Function: overrideMethod] _name: 'overrideMethod' },
  { [AsyncFunction: session] _name: 'session' },
  { [Function] _name: 'securities' },
  { [Function: i18n] _name: 'i18n' },
  { [AsyncFunction] _name: 'eggLoaderTrace' },

transform是我自己写的中间件,问题是,如何修改中间件的加载顺序?

6

app.js 生命周期里面,往 coreMiddleware 里面操作,参考 egg-static