NestJS - 如何使用@Body()装饰器访问POST请求体?

23
import { Controller, Post, Body } from '@nestjs/common';
import { MyService } from 'my.service';
import { MyDto } from './dto/my.dto';

@Controller('my-route')
export class MyController {

    constructor(private readonly _myService: MyService) {}

    @Post()
    async  myMethod(@Body() myDto: MyDto) {
        console.log(myDto); // undefined
        return await this._myService.doStuff(myDto.elementOfInterest); // Passes undefined variable into method.
    }
}

我对在Nest中从POST请求中访问表单数据的正确方式感到困惑。文档和示例都展示了在参数名之前使用@Body()装饰器来简单地获取整个请求体(或者如果使用参数,则是请求体中的特定元素)。然而,在上面的示例中,请求体从未被填充,调用方法时myDto的值为undefined。即使将其类型更改为字符串并仅在POST的请求体中传递单个键/值对,也会导致其值为undefined。

在Nest中处理POST请求体的正确方法是什么?


你添加了任何全局的 PipeInterceptor 吗?我刚从一个空白的 Nest 项目中进行了快速检查,创建了一个带有 @Body() 参数的 @Post() 控制器,并且按预期工作。编辑 - 我刚刚尝试了你的确切代码,没有 MyDto 和 MyService,它也可以工作。你使用的是哪个版本的 NestJS? - VinceOPS
没有管道或拦截器。我在4.5.10和4.6.6中进行了测试,并且具有相同的行为。当我将表单数据发送到服务器时,代码会执行,但是body参数未定义。 - Nate Gardner
11
请记得将请求头中的Content-Type设置为application/json - Kamil Myśliwiec
解决了。 - Nate Gardner
3个回答

31

Kamil Mysliwiec提到的Content-Type是解决方案。

此外,请记得将Content-Type请求头设置为application/json


3

如果有人遇到和我一样的问题。

我也遇到了这个问题,但是对我来说问题出现在main.ts的服务器设置中。

我设置了这段代码以包含用于https的ssl证书,但仅限于生产环境。

let serverOptions = null;
if (environment.production) {
    const httpsOptions = {
        key: fs.readFileSync(environment.sslKeyPath),
        cert: fs.readFileSync(environment.sslCertPath),
    };

    serverOptions = { httpsOptions };
}
const app = await NestFactory.create(AppModule, serverOptions)

但是显然使用选项null创建服务器将会导致它崩溃。

所以我把它改成了像这样的代码,因为它可以与未定义一起使用。

const app = await NestFactory.create(AppModule, serverOptions ?? undefinded)

或者像这样做,因为我不知道将选项设置为undefined是否安全

const app = serverOptions ? await NestFactory.create(AppModule, serverOptions) : await NestFactory.create(AppModule)

希望这能帮助到有类似问题的人。

0
此外,请确保它是一个Post请求而不是get。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接