Midway 获取 row 格式的 Body

因为 Midway web 底层使用的 Egg ,而 Egg 在获取到请求后,会使用 BodyParseropen in new window 进行Body的解析。

BodyParser 默认只支持 json 和 from 两种格式。所以你如果想支持xml格式,需要

  // src/config/config.default.ts
  config.bodyParser = {
    jsonLimit: '100k',
    enableTypes: ['json', 'form', 'text', 'xml'],
    extendTypes: {
      text: ['application/xml'],
    },
  };
1
2
3
4
5
6
7
8

当然,即使这样,你依旧可能没法获取到 body。

因为 BodyParser 的源码中

  async function parseBody(ctx) {
    if (
      enableJson &&
      ((detectJSON && detectJSON(ctx)) || ctx.request.is(jsonTypes))
    ) {
      return await parse.json(ctx, jsonOpts); // eslint-disable-line no-return-await
    }

    if (enableForm && ctx.request.is(formTypes)) {
      return await parse.form(ctx, formOpts); // eslint-disable-line no-return-await
    }

    if (enableText && ctx.request.is(textTypes)) {
      return (await parse.text(ctx, textOpts)) || '';
    }

    if (enableXml && ctx.request.is(xmlTypes)) {
      return (await parse.text(ctx, xmlOpts)) || '';
    }

    return {};
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

会根据 Content-Type 进行解析。

如果你的恰好,收到的请求没Content-Type,那么你打死都不会获取任何内容。

那么谁会不传 `Content-Type` 呢?

中信。 😊

怎么解决?

添加一个中间件,手动解析。

import { Provide } from '@midwayjs/decorator';
import { IWebMiddleware, IMidwayWebNext } from '@midwayjs/web';
import { Context } from 'egg';

// import * as parse from 'co-body';
const parse = require('co-body');

@Provide()
export class notContentTypeMiddleware implements IWebMiddleware {
  resolve() {
    return async (ctx: Context, next: IMidwayWebNext) => {
      console.log(
        '关于中信银行回调没有 content-type 而我不得不写个中间件给他们擦屁股这件事 > \n',
        ctx.request
      );

      if (!ctx.request.headers['content-type']) {
        ctx.request.headers['content-type'] = 'text/plain';
      }

      const res = await parse.text(ctx);
      // console.log('解析出来的 body > ', ctx.request.body);

      ctx.request.body = res;

      await next();
    };
  }
}

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