Flutter Dio无法向Laravel API提交FormData数据求助
问题排查与解决方案
1. 先确认Laravel后端参数接收逻辑
假设你的PeminjamanController的store方法是类似这样的:
public function store(Request $request) { // 验证规则示例 $validated = $request->validate([ 'nama_peminjam' => 'required|string', 'barang_ids' => 'required|array', // 数组参数 'barang_ids.*' => 'exists:barangs,id', // 其他字段... ]); // 处理逻辑 $peminjaman = Peminjaman::create([ 'nama_peminjam' => $validated['nama_peminjam'], // 其他字段... ]); // 关联barang $peminjaman->barangs()->attach($validated['barang_ids']); return response()->json(['message' => 'Peminjaman berhasil dibuat'], 201); }
这里要注意:Laravel接收数组参数时,前端提交的键名需要带[]后缀(比如barang_ids[]),否则后端无法识别为数组。
2. 修正Flutter Dio的FormData构建
如果你的原Dio提交代码是这样的(错误示例):
Future<void> kirimPeminjaman() async { final dio = Dio(); try { FormData formData = FormData.fromMap({ 'nama_peminjam': 'John Doe', 'barang_ids': [1, 2, 3], // 直接传数组,Laravel无法识别 // 其他字段... }); final response = await dio.post( 'http://your-api-url/api/peminjaman', data: formData, ); print(response.data); } catch (e) { print('Error: $e'); } }
这种写法Dio会把数组序列化为barang_ids=1&barang_ids=2&barang_ids=3,但Laravel需要barang_ids[]=1&barang_ids[]=2&barang_ids[]=3才能识别为数组。
修正方案:
方案一:手动添加[]后缀并逐个添加字段
Future<void> kirimPeminjaman() async { final dio = Dio(); try { FormData formData = FormData(); // 添加普通字段 formData.fields.add(MapEntry('nama_peminjam', 'John Doe')); // 添加数组字段,每个元素对应一个带[]的键 List<int> barangIds = [1,2,3]; for (int id in barangIds) { formData.fields.add(MapEntry('barang_ids[]', id.toString())); } // 其他字段同理... final response = await dio.post( 'http://your-api-url/api/peminjaman', data: formData, ); print(response.data); } catch (e) { print('Error: $e'); } }
方案二:使用Dio的FormData.fromMap特殊格式
确保Dio版本较新,直接在键名后加[],Dio会自动拆分数组为多个对应参数:
Future<void> kirimPeminjaman() async { final dio = Dio(); try { FormData formData = FormData.fromMap({ 'nama_peminjam': 'John Doe', 'barang_ids[]': [1, 2, 3], // 键名带[],Dio自动处理为多个barang_ids[]=x // 其他字段... }); final response = await dio.post( 'http://your-api-url/api/peminjaman', data: formData, // Dio会自动为FormData设置Content-Type为multipart/form-data,无需手动添加 ); print(response.data); } catch (e) { print('Error: $e'); } }
3. 调试验证请求内容
在Laravel的store方法中先打印所有接收的参数,确认是否正确获取:
public function store(Request $request) { // 打印所有请求参数,排查是否接收成功 dd($request->all()); // 后续逻辑... }
如果打印结果中没有barang_ids或者是单个值,说明前端提交格式不对;如果是数组,问题可能出在验证规则或后续业务逻辑。
4. 检查跨域与CSRF令牌
- 如果API和Flutter前端不在同一域名下,确保Laravel已配置CORS(可使用
fruitcake/laravel-cors包)。 - 如果路由在
routes/web.php中(而非API路由),需要在FormData中添加_token字段,值为Laravel生成的CSRF令牌。
内容的提问来源于stack exchange,提问作者Filemon Sitanggang
相关产品推荐
相关产品推荐

