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

如何在Next.js中通过FormData实现文件上传?

你看到的控制台FormData为空属于浏览器的默认表现,不是文件没有被添加到FormData中,直接打印FormData对象默认不会展示内部存储的键值对,你可以通过get()方法或者遍历entries()验证内容是否正常写入。

另外你的代码还存在两处可优化调整的点:

  • React/Next.js 中元素的类名属性需要写className而非原生的class,否则样式不会生效
  • 你目前的逻辑是选择文件时就生成FormData,更合理的写法是先把选中的文件存入state,点击提交按钮时再生成FormData发起请求

修正后完整代码示例

import { useState } from 'react'

export default function ExcelUpload() {
  // 存储选中的Excel文件
  const [selectedExcel, setSelectedExcel] = useState(null)

  // 选择文件时仅更新state
  const uploadFile = ({ target: { files } }) => {
    console.log('选中的文件:', files[0])
    setSelectedExcel(files[0])
  }

  // 点击提交按钮时处理上传逻辑
  const handleUpload = async () => {
    if (!selectedExcel) return
    const FilesData = new FormData()
    FilesData.append("excel_file", selectedExcel)

    // 验证FormData内容
    console.log("FormData内存储的文件:", FilesData.get("excel_file"))
    // 遍历所有键值对验证
    for (const [key, value] of FilesData.entries()) {
      console.log(`键:${key},值:`, value)
    }

    // 调用你的Node.js上传接口
    const uploadRes = await fetch('你的Node.js接口地址', {
      method: 'POST',
      body: FilesData
      // 注意:不要手动设置Content-Type请求头,浏览器会自动生成带正确分隔符的multipart/form-data头
    })
    const resData = await uploadRes.json()
    console.log('上传结果:', resData)
  }

  return (
    <div>
      <input
        className="form-control w-25"
        multiple={false}
        type="file"
        id="ExcelFile"
        accept=".xlsx,.xls"
        onChange={uploadFile}
        required
      />
      <button
        type="button"
        disabled={!selectedExcel}
        className="btn btn-primary"
        onClick={handleUpload}
      >
        ADD SOLUTION
      </button>
    </div>
  )
}

注意事项

如果你的接口需要携带鉴权信息、自定义头,直接在fetch配置的headers字段添加即可,不要手动修改Content-Type,手动设置会覆盖浏览器自动生成的boundary分隔符,导致接口无法正常解析上传的文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:15:00