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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:25:31