如何在Next.js中处理POST请求?

76
我想在我的next.js api文件夹中设置一个POST路由,我将数据发送到该路由,但无法解析数据以实际保存到数据库中。如何处理next.js中的POST路由是最好的方式,特别是以JSON格式解析数据?
3个回答

101

要在Next.js API路由中使POST请求正常工作,您需要执行以下3个步骤:

  • 将方法限制为POST
  • 使用JSON.parse()解析路由中的JSON(在NextJS v12+中不需要)
  • 向后端发送请求

https://nextjs.org/docs/api-routes/api-middlewares

API路由

Next.js中的API路由默认支持所有类型的请求,包括GET、POST、DELETE等。因此虽然不是必需的,但将路由限制为您想要支持的方法是一个好主意。

在您的情况下,如果您只想支持某个路线上的POST请求,则可以使用req.method来过滤非POST请求。

if (req.method !== 'POST') {
  res.status(405).send({ message: 'Only POST requests allowed' })
  return
}
为了解析JSON,你可以使用JSON.parse()。如果你正在使用NextJS V12+,并且没有设置bodyParser: false,则不需要这样做。
const body = JSON.parse(req.body)

把所有东西结合起来,你的API路由应该像这样:

// pages/route-name.js

export default function handler(req, res) {
  if (req.method !== 'POST') {
    res.status(405).send({ message: 'Only POST requests allowed' })
    return
  }


  // not needed in NextJS v12+
  const body = JSON.parse(req.body)

  // the rest of your code
}

发送请求

最后,您需要从前端代码向后端发送POST请求。您可能已经知道如何做到这一点,但为了完整起见还是提一下。

fetch('/api/route-name', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(objectWithData),
})

简要说一下,您不需要为在Next.js中使用fetch而担心跨浏览器兼容性问题。Next.js会在需要时自动添加polyfill


14
与其返回一般的“400 Bad Request”错误,更恰当的做法是返回“405 Method Not Allowed”。 - aalaap
2
好的调用,已更新答案,使用405状态码。 - Nick
有没有可能不使用NextJS的API来完成它?我的NextJS应用程序托管在vercel上,而且所有的API都是外部的。我想避免使用NextJS服务器端API,以避免在vercel中对函数执行的限制。我希望通过向页面路由本身发送POST请求,如/cars,但是POST /cars和NextJS使用其SSR功能来呈现页面,其中使用getServerSideProps(...)来编写从外部API获取数据的逻辑。 - shashwat
在 Vercel 上使用 Next.js 时,您不需要担心任何功能限制。当部署到 Vercel 上时,Next.js 站点会被合并成一个单独的无服务器函数(如果只有一个函数无法满足需求,则尽可能少)。所有页面和 API 路由都通过该单个无服务器函数提供服务。在 Vercel 的限制方面,向 API 路由发送 Post 请求等同于向页面发送请求。https://vercel.com/docs/concepts/limits/overview#serverless-functions-created-per-deployment - Nick
只要从前端发送请求时,头部包含 Content-Type: application/json (适用于 Next.js v12+)。 - 1antares1

28
关于这个问题,答案并不确定。在 Next.js v12 中,如果你没有显式地在 API 路由的导出配置中设置 bodyParser: false(请参见 https://nextjs.org/docs/api-routes/api-middlewares),则不需要在 API 路由中使用 JSON.parse(req.body)。例如,如果请求的 content-typeapplication/json,那么 req.body 将自动解析为一个对象。在这种情况下,由于内容已经被预先解析成了对象,尝试在 API 中运行 JSON.parse(req.body) 很可能会抛出错误。

2
注意:如果使用 fetch 发送请求,请记得将 Content-Type 设置为 application/json,否则 Next.js 不会自动解析。 - Sandro Maglione

3
在Nextjs 13.4中,你可以使用路由处理程序
import { NextResponse } from 'next/server'
 
export async function POST() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'API-Key': process.env.DATA_API_KEY,
    },
    body: JSON.stringify({ time: new Date().toISOString() }),
  })
 
  const data = await res.json()
 
  return NextResponse.json(data)
}

要获取最新的和现成的路由处理程序模板以及更多内容,请使用 Next.js 13+ 强大代码片段 | TypeScript/Javascript


调用res.json()时,不要忘记使用await - undefined

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