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

Nuxt3+Node.js使用Multer上传文件失败、req.file为空

问题根因

两个核心问题导致multer拿不到上传文件:

  • 封装的请求方法错误展开FormData对象:{ token: token.value, ...body }这行代码会把FormData类型的请求体转成普通空对象(FormData存储的键值对不可枚举,展开操作无法读取内部存储的文件、字段),最终请求里根本没有带上csv文件字段。
  • 手动设置Content-Type: multipart/form-data请求头不合法:multipart/form-data请求必须携带浏览器自动生成的boundary分隔符参数,手动写死这个头会丢失boundary,服务端的multer无法正确切割请求内容,自然识别不到文件字段。
修复步骤
  1. 修正自定义$postFetch插件的逻辑,区分普通请求和FormData请求的处理逻辑,不要无脑展开请求体,也不要覆盖浏览器自动生成的Content-Type头,修正后代码如下:
export default defineNuxtPlugin(async () => {
  return {
    provide: {
      postFetch: async (url, body,headers={}) => {
        let token = useCookie('token');
        let finalBody = body
        const finalHeaders = {...headers}

        // FormData类型请求单独处理
        if (body instanceof FormData) {
          // 把token追加到FormData内部
          if (token.value) body.append('token', token.value)
          // 删除手动设置的Content-Type,让浏览器自动生成带合法boundary的请求头
          delete finalHeaders['Content-Type']
        } else {
          // 普通JSON请求才做对象合并
          finalBody = { token: token.value, ...body }
        }

        return await $fetch(url, {
          method: 'post',
          body: finalBody,
          baseURL: useRuntimeConfig().API_BASE,
          headers: finalHeaders
        }).catch((error) => error.data)
      }
    }
  }
})
  1. 调整前端文件上传的调用代码,去掉手动传入的Content-Type配置:
async function fileSelected(e) {
  let formData = new FormData();
  formData.append("csv", e.target.files[0]);
  // 不需要手动设置请求头
  const res = await $postFetch("/admin/sendNewQuestionCSV", formData);
}
额外注意事项
  • 确认服务端配置的./uploads/目录存在,且当前Node.js进程对该目录有写入权限,否则multer存储文件时会抛出错误。
  • 如果你使用的是Nuxt3自带的Server路由(/server/api目录下的接口)而非独立的Express服务,不建议使用multer解析文件,直接用Nuxt3内置的readMultipartFormData方法即可,避免出现底层请求体被提前消费导致multer解析失败的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:33:28