如何在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
相关产品推荐
相关产品推荐

