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

NextJS中Axios POST请求后无法获取FormData问题排查

问题描述

在Next.js应用中,通过Axios从客户端向pages/api后端发送FormData时,后端pages/api/middleware.js里打印req.body和req.files均为undefined,解析后得到的fields是{"undefined":["[object Promise]"]},files为空对象。

客户端发送代码:

// ./index.js
uploadFile = async (base64) => {
  try {
    const formData = new FormData()
    formData.append('name', 'myName')
    formData.append('description', 'myDescription')
    formData.append('file', base64)
    const { data } = await axios.post('/api/upload', formData, {headers: { 'Content-Type': 'multipart/form-data' }})

    return true

  } catch (ex) {
    console.error(ex)
    return null
  }
}

后端中间件接收代码:

// ./pages/api/middleware.js
middleware.use((req, res, next) => {
  const form = new multiparty.Form()

  console.log(req.body) // undefined
  console.log(req.files) // undefined

  form.parse(req, function (err, fields, files) {
    if (err) {
      console.log(err)
    }
    req.body = fields 
    req.files = files
    console.log(fields) // {"undefined":["[object Promise]"]}
    console.log(files) // {}
    next()
  })
})
问题分析与解决
  • 手动设置Content-Type导致解析失败
    Axios请求里手动指定'Content-Type': 'multipart/form-data'会覆盖浏览器自动生成的带boundary的请求头,后端没有boundary信息就无法正确拆分FormData里的字段。
    解决:删掉Axios的headers配置,让FormData自动生成正确的请求头:

    const { data } = await axios.post('/api/upload', formData)
    
  • base64字符串无法被识别为文件
    直接把base64字符串作为file字段值传入FormData,multipart/form-data规范要求文件字段是Blob或File对象,纯字符串会被当作普通文本,后端无法识别为文件。
    解决:先把base64转成Blob对象再添加到FormData:

    // 工具函数:base64转Blob
    function base64ToBlob(base64) {
      const arr = base64.split(',')
      const mime = arr[0].match(/:(.*?);/)[1]
      const bstr = atob(arr[1])
      let n = bstr.length
      const u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new Blob([u8arr], { type: mime })
    }
    
    // 在uploadFile中替换原file字段的添加逻辑
    const fileBlob = base64ToBlob(base64)
    formData.append('file', fileBlob, 'custom-filename.jpg') // 第三个参数可选,设置文件名
    
  • 中间件应用范围与请求流消耗问题
    Next.js API路由默认不解析multipart/form-data,用multiparty解析是正确的,但要确保这个中间件只针对/api/upload这类需要处理表单的路由,避免和其他解析中间件(比如body-parser的json/urlencoded)冲突——如果其他中间件提前读取了请求流,multiparty就无法再解析数据。
    优化:限定中间件的应用路径:

    // 只对/api/upload应用该解析中间件
    middleware.use('/api/upload', (req, res, next) => {
      const form = new multiparty.Form()
      form.parse(req, function (err, fields, files) {
        if (err) {
          console.error(err)
          return res.status(400).json({ error: '表单解析失败' })
        }
        req.body = fields 
        req.files = files
        next()
      })
    })
    

内容的提问来源于stack exchange,提问作者Pm Rivière

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:55:19