向 Fastify 发出 POST 请求时,JSON 未被解析以进行验证

Posted

技术标签:

【中文标题】向 Fastify 发出 POST 请求时,JSON 未被解析以进行验证【英文标题】:JSON not being parsed for validation when doing a POST request to Fastify 【发布时间】:2021-06-26 18:19:24 【问题描述】:

在我的路线中,我有以下内容:

const reservationSchema = 
  body: 
    type: 'object',
    required: ['in', 'out', 'guests', 'language', 'roomsSelected'],
    properties: 
      language: 
        type: 'string',
      ,
      // ... several other property validations here
    
  
;

fastify.post(
  '/api/reservations/:slug',
   schema: reservationSchema ,
  reservationsController.addReservation
);

我像这样从 React 发送 POST 请求:

const response = await fetch(process.env.REACT_APP_API_HOSTNAME + '/api/reservations/' + property.slug, 
  method: 'POST',
  body: JSON.stringify(requestBody)
);

当我查看请求时,我可以看到它正在正确发送 JSON:

但是我收到以下回复:


  "statusCode":400,
  "error":"Bad Request",
  "message":"body should be object"

我是否遗漏了一些东西来自动将 POST 正文解析为 Fastify 中的对象,以便我可以使用验证模式对其进行验证?即使在我的reservationsController.addReservation() 函数中,我也需要在req.body 上手动执行JSON.parse()

【问题讨论】:

【参考方案1】:

来自fetch() 文档:

请求和响应(以及 fetch() 函数的扩展)都将尝试智能地确定内容类型。如果字典中没有设置,请求也会自动设置 Content-Type 标头。

但是,(至少在 Chrome 中),当您发送 JSON 字符串时,它不会智能地确定该字符串是 JSON,而是将 Content-Type 标头作为 text/plain;charset=UTF-8 发送。由于服务器接收到这个 Content-Type 标头,因此它假定您正在发送计划文本字符串,因此不会将其解析为 JSON。

要使服务器自动将正文解析为 JSON,您需要确保将 Content-Type 标头设置为 application/json。像这样:

const response = await fetch(process.env.REACT_APP_API_HOSTNAME + '/api/reservations/' + property.slug, 
  method: 'POST',
  headers: 
    'Content-Type': 'application/json',
  ,
  body: JSON.stringify(requestBody)
);

【讨论】:

以上是关于向 Fastify 发出 POST 请求时,JSON 未被解析以进行验证的主要内容,如果未能解决你的问题,请参考以下文章

使用 Angular 2 向 API 发出 POST 请求时出错

向 Laravel Api 发出 POST 请求时,React Native 获取一个空数组

如何在 Laravel-8 和 InertiaJs 中向服务器发出 POST 请求时在浏览器中保留当前的 ​​GET url

为啥我在尝试在 iOS Swift 中向服务器发出 post 请求时收到此错误:在展开 Optional 值时意外发现 nil?

在事务中从 WCF 服务向 REST API 发出 Post 请求

在 Express.js 上使用 Axios 向 Spotify API 发出 POST 请求时出现错误 400