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

Laravel5.8获取Vue经Axios发送的FormData文件失败

问题根因

当前实现有3个核心错误,直接导致Laravel无法接收上传文件:

  • 错误将FormData实例作为普通对象的属性赋值,axios序列化请求时会把嵌套的FormData解析为空值,不会正确读取内部存储的文件
  • 提交时直接发送Vue data中定义的普通JSON对象,没有将所有业务字段挂载到顶层FormData实例中
  • 未给axios配置multipart/form-data请求头,请求默认以application/json格式发送,本身不支持文件传输
分步修复方案

1. 调整前端基础定义与文件选择逻辑

不要在文件选择回调中单独实例化FormData,提前修正data结构,文件选择后直接存储原始文件列表即可:

// Vue实例data定义
data() {
  return {
    form: {
      discount_amount: '',
      student_id: '',
      batch_id: '',
      batch_fee: '',
      attachments: null,
      selected_bill_months: []
    }
  }
},
methods: {
  // 文件选择回调
  setFile(e) {
    // 直接存储选中的文件列表,不要提前封装FormData
    this.form.attachments = e.target.files
  },

注意:文件上传input标签必须加multiple属性,支持多文件选择

2. 修正表单提交逻辑

提交时统一实例化顶层FormData对象,将所有业务字段、数组值、文件逐个追加到FormData中,配置正确请求头后再发送请求:

async submitForm() {
  // 补全业务字段
  this.form.student_id = this.currentStudent.id
  this.form.batch_id = this.currentBatch.id
  this.form.batch_fee = this.currentBatch.fee

  // 实例化顶层FormData,所有提交字段都直接挂载到该实例
  const submitData = new FormData()

  // 追加普通单值字段
  submitData.append('discount_amount', this.form.discount_amount)
  submitData.append('student_id', this.form.student_id)
  submitData.append('batch_id', this.form.batch_id)
  submitData.append('batch_fee', this.form.batch_fee)

  // 追加多选账单月份,数组类型字段key必须加[]后缀,Laravel才能正确识别为数组
  this.form.selected_bill_months.forEach(month => {
    submitData.append('selected_bill_months[]', month)
  })

  // 追加多文件,同样使用带[]后缀的key
  if (this.form.attachments) {
    for (let i = 0; i < this.form.attachments.length; i++) {
      submitData.append('attachments[]', this.form.attachments[i])
    }
  }

  // 发送请求,必须配置multipart/form-data请求头
  const res = await axios.post('/university/api/discounts', submitData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
  console.log(res.data)
}

3. Laravel后端接收逻辑

修复前端后,后端可直接通过请求实例获取文件和字段,参考验证逻辑如下:

public function store(Request $request)
{
    // 调试时可打开下面注释查看所有提交字段
    // dd($request->all());
    
    $validated = $request->validate([
        'discount_amount' => 'required|numeric',
        'student_id' => 'required|exists:students,id',
        'batch_id' => 'required|exists:batches,id',
        'batch_fee' => 'required|numeric',
        'selected_bill_months' => 'required|array',
        'attachments' => 'required|array',
        'attachments.*' => 'file|max:10240|mimes:pdf,jpg,png,doc,docx' // 单文件校验规则
    ]);

    // 后续业务逻辑:通过$request->file('attachments')即可拿到所有上传的文件实例
}
避坑提醒
  • 所有数组类型的提交字段(多文件、多选值),FormData对应的key必须加[]后缀,否则Laravel只能接收到最后一个值,甚至识别为空
  • 禁止将FormData实例嵌套在普通JSON对象中传递,必须直接将顶层FormData实例作为axios的请求体参数
  • 如果项目配置了axios全局拦截器,需要检查是否存在强制把请求体序列化为JSON的逻辑,发送multipart请求时要跳过该序列化逻辑
  • 若使用PUT/PATCH路由提交文件,Laravel需要额外在FormData中追加_method字段对应请求方法,同时axios统一用post发送,避免部分浏览器不支持put请求传文件的问题

内容的提问来源于stack exchange,提问作者Abdul Raheem Ghani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:09:14