NextJs API 端点返回不带“消息”或“正文”的响应对象

问题描述 投票:0回答:1

我有一个 NextJs 应用程序,其中

  1. 用户可以填写一些输入字段并提交表单(Formik Form)。
  2. 表单提交由 API 路由处理以进行一些计算(我可以在客户端执行此操作,但在本例中需要在服务器端执行此操作)

除了 API 端点返回给客户端的响应对象之外,一切都工作正常

/pages/api/calculation.js

const handler = (req, res) => {
  // deny the request if not post method
  req.method !== 'POST' &&
    res.status('403').json({
      status: 403,
      message: 'Forbidden',
    });

  // all the logic goes here

  // return the response
  // also tried a few others like (res.status(200).json({ message: 'Hello from Next.js!' });
  return res.send({ status: 200, message: 'Hello from Next.js!' });
};

export default handler;

/pages/index.jsx

Inside Formik's onSubmit prop

fetch('/api/mbti/result', {
   method: 'POST',
   headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
   },
   body: JSON.stringify(values),
}).then((res) => {
   console.log(res);

   if (res.status === 200) {
      resetForm(); // reset form
   }
});

这是响应对象

body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
url: "http://localhost:3000/api/calculation"

在客户端,我想从 API 返回的响应对象访问正文中的“消息”。目前,响应对象内的主体只是

(...)
,如您在上面看到的。

reactjs next.js formik
1个回答
3
投票

由于您使用的是 fetch,因此您需要将 Response 主体转换为 json。默认情况下,响应正文是一个 Readable Stream

您可以使用 Promise thenables:

fetch('/api/mbti/result', {
  method: 'POST',
  headers: {
    Accept: 'application/json, text/plain, */*',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(values),
}).then(res => {
  if (!res.ok) {
    res.text().then(err => throw new Error(err));
  }

  return res.json();
}).then(data => {
  console.log('API response data', data);

  resetForm(); // reset form
}).catch(err => console.error(err));

或者,我建议您使用 async/await,因为它更干净一些:

const onSubmit = handleSubmit(async values => {
  try {
    const res = await fetch('/api/mbti/result', {
      method: 'POST',
      headers: {
        Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(values),
    });
    
    if (!res.ok) {
      const error = await res.text();
      throw new Error(error);
    }
    
    const data = await res.json();
    
    console.log("API response data", data);

    resetForm();
  } catch(err) {
    console.error(err);
  }
});

相关说明,您的 API 端点中有一个错误,它会在发送标头后尝试发送标头:

const handler = (req, res) => {
  // deny the request if not post method

  // if you don't return here, then it'll continue down the call stack and try to send a valid response as well
  if(req.method !== 'POST')
    return res.status('403').json({
      status: 403,
      message: 'Forbidden',
    });


  // return the valid response
  return res.send({ status: 200, message: 'Hello from Next.js!' });
};

export default handler;
© www.soinside.com 2019 - 2024. All rights reserved.