PayloadTooLargeError: request entity too large. How solve it in NestJS?

PayloadTooLargeError: request entity too large. How solve it in NestJS?

我需要发送包含 base64 字符串的请求,但它太大(可能大约 2 mb)。

但是服务器抛出下一个异常,如何避免这个错误:

[Nest] 1666  - 11/01/2021, 1:50:58 PM   ERROR [ExceptionsHandler] request entity too large
gateway-client  | PayloadTooLargeError: request entity too large
gateway-client  |     at readStream (/srv/app/node_modules/raw-body/index.js:155:17)
gateway-client  |     at getRawBody (/srv/app/node_modules/raw-body/index.js:108:12)
gateway-client  |     at read (/srv/app/node_modules/body-parser/lib/read.js:77:3)
gateway-client  |     at jsonParser (/srv/app/node_modules/body-parser/lib/types/json.js:135:5)
gateway-client  |     at Layer.handle [as handle_request] (/srv/app/node_modules/express/lib/router/layer.js:95:5)
gateway-client  |     at trim_prefix (/srv/app/node_modules/express/lib/router/index.js:317:13)
gateway-client  |     at /srv/app/node_modules/express/lib/router/index.js:284:7
gateway-client  |     at Function.process_params (/srv/app/node_modules/express/lib/router/index.js:335:12)
gateway-client  |     at next (/srv/app/node_modules/express/lib/router/index.js:275:10)
gateway-client  |     at expressInit (/srv/app/node_modules/express/lib/middleware/init.js:40:5)

我的 main.ts 包括:

async function bootstrap() {  
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  
  // app.enableCors({
  //   origin: '*',
  // });

  const config = new DocumentBuilder()
    .setTitle('API client gateway')
    .setDescription('API client gateway full documentation')
    .setVersion('v0.0.1')
    .addTag('')
    .addBearerAuth(
      {
        type: 'http',
        scheme: 'bearer',
        bearerFormat: 'JWT',
        name: 'JWT',
        description: 'Enter JWT token',
        in: 'header',
      },
      'jwt-token',
    )
    .build();

  const document = SwaggerModule.createDocument(app, config);

  SwaggerModule.setup('/api/docs', app, document);


  await app.init();

  app.use(express.json({limit: "50mb"})) //For JSON requests
  app.use(express.urlencoded({
    limit: "50mb",
    extended: false
  }));

  await app.listen(AppConfig.Port);
}

bootstrap();

在您的 main.ts 文件中(很可能是 bootstrap() 方法)获取 Express App 实例并设置 JSON 解析器限制:

import { json } from 'body-parser';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule,
    { bodyParser: false });

  app.use(json({ limit: '5mb' }));

  ...
}

编辑:如果您通过代理(例如 nginx)访问应用程序,请确保也有相同的限制。

如果您想使用 body-parser 的更惯用版本(在您的 bootstrap 函数中禁用它之后):

// json-body-parser.middleware.ts
import { NestMiddleware } from '@nestjs/common';
import bodyParser from 'body-parser';

type JsonBodyParserOpts = bodyParser.OptionsJson;

// As we're not using DI, we don't need to mark this as Injectable
export class JsonBodyParserMiddleware implements NestMiddleware {
  private readonly options: JsonBodyParserOpts = {
    limit: '5mb',
  };

  use = bodyParser.json(this.options);
}
// in your main/root module
// ...
export class AppModule implements NestModule {
  configure(middlewareConsumer: MiddlewareConsumer): void {
    middlewareConsumer
      .apply(JsonBodyParserMiddleware)
      .forRoutes({
        path: '*',
        method: RequestMethod.ALL,
      });
  }
}

我更愿意尽可能避免 app.use,让 bootstrap 功能更清洁。

或者你可以让它从外部动态配置,做一些像 this.

在此处了解有关 Nestjs 中间件的更多信息:https://docs.nestjs.com/middleware