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

Flutter Dio发送FormData遇415错误,求正确传文件及进度显示方案

解决Dio上传FormData出现415错误及实现上传进度、响应获取的方案

错误原因分析

415错误是因为请求的Content-Type设置错误:你手动指定了application/json,但发送的是FormData,API无法识别这种格式。另外,文件列表的处理存在异步问题,map里的async会返回Future<MultipartFile>的列表,而非直接的MultipartFile列表,导致FormData构造异常。

修正后的完整代码

1. 初始化Dio(移除错误的Content-Type)

Dio dio = Dio(
  BaseOptions(
    baseUrl: baseUrl,
    headers: {
      'Accept': 'application/json',
      'Authorization': 'Bearer ${APIVariables.token}',
      // 移除Content-Type: application/json,Dio会自动为FormData设置multipart/form-data
    },
  ),
);

2. 正确构造FormData(处理文件异步列表)

// 先处理文件列表,等待所有MultipartFile创建完成
List<MultipartFile> files = await Future.wait(
  complaint.files.map((file) async => MultipartFile.fromFile(
        file.path,
        filename: basename(file.path),
      )),
);

FormData formData = FormData.fromMap({
  "id": complaint.id,
  "title": complaint.title,
  "description": complaint.description,
  "complainedPosition": complaint.complainedPosition,
  "deptId": complaint.departmentId,
  "typeId": complaint.typeId,
  "priortyId": complaint.priorityId,
  "files": files,
});

3. 发送请求并监听上传进度、获取响应

try {
  Response response = await dio.post(
    'Complaint',
    data: formData,
    // 监听上传进度
    onSendProgress: (int sent, int total) {
      if (total != -1) {
        double progress = (sent / total) * 100;
        print('上传进度:${progress.toStringAsFixed(2)}%');
        // 这里可以更新UI显示进度,比如用StatefulWidget的setState
      }
    },
  );

  // 上传完成后处理响应
  if (response.statusCode == 200 || response.statusCode == 201) {
    print('上传成功,响应数据:${response.data}');
    // 根据API返回的结构处理业务逻辑
  }
} on DioException catch (e) {
  // 捕获错误并处理
  print('上传失败:${e.message}');
  if (e.response != null) {
    print('响应错误信息:${e.response?.data}');
  }
}

关键注意点

  • Content-Type自动处理:当发送FormData时,Dio会自动添加Content-Type: multipart/form-data; boundary=xxx的请求头,无需手动设置,手动设置反而会导致格式不匹配。
  • 异步文件列表处理:MultipartFile.fromFile是异步方法,必须用Future.wait等待所有文件实例创建完成后再传入FormData,否则会传入Future对象而非实际的文件对象。
  • 进度监听:通过onSendProgress回调可以获取已发送字节数和总字节数,计算出进度百分比后更新UI。
  • 错误捕获:使用try-catch捕获DioException,可以区分网络错误、响应错误等不同情况,方便调试和用户提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:54:20