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

如何在Vue.js+Laravel API中使用Async Await实现文件/图片上传

问题描述

我有一个需要保存图片及其他输入数据的表单,希望使用Async Await调用Laravel API完成操作。目前向控制器传递数据时出现错误,返回undefined,不清楚Fetch API POST请求后后续操作,也不知如何正确传递所有数据并保存到数据库。

Laravel控制器代码

public function addbusiness(Request $request){ 
    return response()->json(["message" => "up"]);
}

Vue.js的data定义

data() { 
    return { 
        items: [{ 
            rank_id: '1', 
            product_name: 'Multi Handle Tote Bag with Kalesa Scenery', 
            orders: 2500, 
            sales: '₱ 350,000', 
            rating: '5' 
        }], 
        redirectChecked: false, 
        dropdownIndex: null, 
        selectedBarangay: 'Select Barangay', 
        barangayList: ['Bangkal', 'Bel-Air', 'Carmona', 'Dasmariñas', 'Forbes Park'], 
        searchQuery: '', 
        termsAndConditions: false, 
        addinfo: {}, 
        busname: '', 
        bustype: '', 
        email: '', 
        contact: '', 
        country: '', 
        city: '', 
        barangay: '', 
        tin: '', 
        address: '', 
        clearance: '', 
        contractlease: '', 
        busregistration: '', 
        liabilityinsurance: '', 
        redirectweb: '', 
        lease: ''
        // 原代码重复定义了clearance,已删除重复项
    };
}

Vue.js的methods函数

methods: { 
    upclearance(event){ 
        this.clearance = event.target.files[0]
    }, 
    uplease(event){ 
        this.contractlease = event.target.files[0]
    }, 
    upregistration(event){ 
        this.busregistration = event.target.files[0]
    }, 
    upinsurance(event){ 
        this.liabilityinsurance = event.target.files[0]
    }, 
    async addbusinfo(e){ 
        e.preventDefault(); 
        const fd = new FormData(); 
        fd.append('clearance', this.clearance, this.clearance.name); 
        fd.append('contractlease', this.contractlease, this.contractlease.name); 
        fd.append('busregistration', this.busregistration, this.busregistration.name); 
        fd.append('liabilityinsurance', this.liabilityinsurance, this.liabilityinsurance.name); 
        fd.append('busname', this.busname); 
        fd.append('bustype', this.bustype); 
        fd.append('email', this.email); 
        fd.append('contact', this.contact); 
        fd.append('country', this.country); 
        fd.append('city', this.city); 
        fd.append('barangay', this.barangay); 
        fd.append('tin', this.tin); 
        fd.append('address', this.address); 

        try {
            const response = await fetch("http://localhost:8000/api/addbusiness",{ 
                method: 'POST', 
                body: fd, // 替换原错误的data参数为body
                headers: {
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                }
            });

            if (!response.ok) {
                throw new Error(`请求失败,状态码:${response.status}`);
            }

            const result = await response.json();
            console.log(result);
            // 这里可添加成功后操作:重置表单、提示用户、页面跳转等
        } catch (error) {
            console.error('请求出错:', error);
            // 这里处理错误:给用户弹窗提示等
        }
    }
}
问题修复与完善步骤

1. 修正Fetch API参数错误

  • Fetch POST请求传递表单数据的参数是body而非data,原代码的data: fd是错误写法,需改为body: fd。
  • 无需手动设置Content-Type,浏览器会自动为FormData添加multipart/form-data头。
  • 添加CSRF令牌头:Laravel默认启用CSRF保护,需在请求头里带上页面meta标签中的CSRF令牌。
  • 统一用async/await+try/catch语法,避免then链式调用的混乱,同时方便捕获和处理异常。

2. 完善Laravel控制器逻辑

要正确接收FormData并保存文件与数据,修改控制器代码如下:

use Illuminate\Support\Facades\Storage;

public function addbusiness(Request $request){ 
    // 验证请求数据
    $validated = $request->validate([
        'busname' => 'required|string',
        'bustype' => 'required|string',
        'email' => 'required|email',
        'clearance' => 'required|file|mimes:pdf,jpg,jpeg,png|max:2048', // 限制文件类型和大小
        'contractlease' => 'required|file|mimes:pdf,jpg,jpeg,png|max:2048',
        'busregistration' => 'required|file|mimes:pdf,jpg,jpeg,png|max:2048',
        'liabilityinsurance' => 'required|file|mimes:pdf,jpg,jpeg,png|max:2048',
        // 其他字段按需添加验证规则
    ]);

    // 处理文件上传,保存到storage/app/public目录(需先执行php artisan storage:link生成软链)
    $filePaths = [];
    $fileFields = ['clearance', 'contractlease', 'busregistration', 'liabilityinsurance'];
    foreach ($fileFields as $field) {
        if ($request->hasFile($field)) {
            $filePaths[$field] = $request->file($field)->store('business_documents', 'public');
        }
    }

    // 保存业务数据到数据库(假设存在Business模型)
    $business = \App\Models\Business::create([
        'name' => $request->busname,
        'type' => $request->bustype,
        'email' => $request->email,
        'contact' => $request->contact,
        'country' => $request->country,
        'city' => $request->city,
        'barangay' => $request->barangay,
        'tin' => $request->tin,
        'address' => $request->address,
        'clearance_path' => $filePaths['clearance'],
        'contract_lease_path' => $filePaths['contractlease'],
        'registration_path' => $filePaths['busregistration'],
        'insurance_path' => $filePaths['liabilityinsurance'],
    ]);

    return response()->json([
        "message" => "业务信息保存成功",
        "data" => $business
    ], 201);
}

3. 修复Vue数据定义问题

原data中重复定义了clearance字段,会导致数据逻辑混乱,已删除重复项。

4. 调试技巧

  • 在Vue的addbusinfo方法中,可打印FormData内容确认数据是否正确:
    for (let [key, value] of fd.entries()) {
        console.log(`${key}:`, value);
    }
    
  • 在Laravel控制器中,可先打印请求内容确认是否接收到数据:
    dd($request->all()); // 查看所有表单字段
    dd($request->files); // 查看上传的文件信息
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:17:10