You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js API函数单次调用多次执行,首次请求无POST数据问题排查

问题分析与解决方案

核心问题

  1. 首次调用无POST数据:SWR默认使用GET请求发起API调用,而你的服务端代码从req.body(仅POST请求携带)获取submissionId,首次GET请求自然没有body数据,触发"contact does not exist"错误。
  2. 后端函数多次执行:Next.js动态路由的router.query在页面初始加载时可能为空(参数需要时间解析),导致SWR先发起一次无submissionId的请求,等参数加载完成后又发起第二次有效请求,所以后端函数执行两次。

修复方案

方案1:改用GET传递参数(更符合当前SWR的使用习惯)

调整服务端从req.query获取参数,同时确保客户端在submissionId存在时才发起请求:

客户端代码修改:

export default function Customer () {
  const router = useRouter()
  const { id: submissionId } = router.query

  // 只有submissionId存在时才发起请求
  const { data: customer, error } = useSWR(submissionId ? ['/api/jotform/get-client', submissionId] : null, fetcher)
...
}

// 调整fetcher,把submissionId作为查询参数传递
const fetcher = async (url, submissionId) => {
  const res = await fetch(`${url}?submissionId=${submissionId}`)
  return res.json()
}

服务端代码修改:

export default async function handler (req, res) {
  try {
    const customers = await axios.get(`https://api.jotform.com/form/${jotformAPI.form_id}/submissions?apiKey=${jotformAPI.key}`)

    // 从req.query获取submissionId,而非req.body
    const { submissionId } = req.query
    if (!submissionId) {
      return res.status(400).json({ error: 'Missing submissionId' })
    }
    
    const customer = customers.data.content.find(client => client.id === submissionId)
    if (!customer) throw new Error('contact does not exist')
    
    // 后续逻辑...
    res.status(200).json(customer)
  } catch (err) {
    res.status(404).json({ error: err.message })
  }
}

方案2:改用POST请求(如果业务需要POST)

修改SWR的fetcher发起POST请求,同样确保submissionId存在才触发请求:

客户端代码修改:

export default function Customer () {
  const router = useRouter()
  const { id: submissionId } = router.query

  const { data: customer, error } = useSWR(submissionId ? ['/api/jotform/get-client', submissionId] : null, async (url, id) => {
    const res = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ submissionId: id })
    })
    return res.json()
  })
...
}

服务端代码补充:
先判断请求方法,确保仅处理POST请求:

export default async function handler (req, res) {
  // 只接受POST请求
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' })
  }

  try {
    const customers = await axios.get(`https://api.jotform.com/form/${jotformAPI.form_id}/submissions?apiKey=${jotformAPI.key}`)

    const { submissionId } = req.body
    if (!submissionId) {
      return res.status(400).json({ error: 'Missing submissionId' })
    }
    
    const customer = customers.data.content.find(client => client.id === submissionId)
    if (!customer) throw new Error('contact does not exist')
    
    // 后续逻辑...
    res.status(200).json(customer)
  } catch (err) {
    res.status(404).json({ error: err.message })
  }
}

额外优化建议

  • 可以在服务端缓存Jotform API的响应,避免每次请求都调用外部API,减少重复请求和延迟。
  • 开发模式下Next.js会有热重载,可能导致API路由重复执行,生产环境会缓解这个问题。

内容的提问来源于stack exchange,提问作者ilyo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:30:52