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

Dio上传POST请求突然无法发送,求排查解决办法

Dio文件上传POST请求无法发起的排查方案

1. 先补全代码语法错误

你上传方法里的postUri调用有语法问题,uri参数后面少了逗号,这会导致代码无法正确执行:

return await client.postUri(
  uri,  // 补上这个逗号
  data: data,
  options: options ?? Options(contentType: Headers.multipartFormDataContentType),
);

虽然你说之前正常,但大概率是修改代码时误删了这个逗号,先补上再测试。

2. 校验文件与权限

  • 先确认filePath对应的文件真的存在,在构建FormData前加个校验:
    Future<FormData> get toFormData async {
      final file = File(filePath!);
      if (!(await file.exists())) {
        throw Exception("找不到文件: $filePath");
      }
      return FormData.fromMap({
        ...toJson(),
        "date": DateTime.now().toIso8601String(),
        "file": await MultipartFile.fromFile(file.path, filename: name),
      });
    }
    
  • 你用的是Android SDK35(Android 14),要注意权限:如果是读取媒体文件,得申请READ_MEDIA_IMAGES/READ_MEDIA_VIDEO这类权限,旧的READ_EXTERNAL_STORAGE已经失效,检查你的权限配置和运行时权限申请是否到位。

3. 换一种FormData构建方式

Dio 5.x对FormData的fromMap处理有细节变化,试试手动构建FormData,避免隐式转换问题:

Future<FormData> get toFormData async {
  final formData = FormData();
  // 逐个添加普通字段
  if (module != null) formData.fields.add(MapEntry("module", module!));
  if (type != null) formData.fields.add(MapEntry("type", type!));
  if (payload != null) formData.fields.add(MapEntry("payload", payload!));
  formData.fields.add(MapEntry("date", DateTime.now().toIso8601String()));
  // 添加文件
  formData.files.add(MapEntry(
    "file",
    await MultipartFile.fromFile(filePath!, filename: name),
  ));
  return formData;
}

4. 排查请求阻塞点

  • 确认上传操作在异步环境执行,别在UI线程做同步阻塞的事,比如调用上传的地方如果是同步函数,会卡住请求发起。
  • 加日志和CancelToken监听,确认方法是否被调用:
    final cancelToken = CancelToken();
    print("准备发起上传请求");
    final result = await upload(
      uri: yourUploadUri,
      data: formData,
      options: Options(contentType: Headers.multipartFormDataContentType),
    );
    
    如果打印了日志但拦截器没触发,说明请求在Dio内部卡住了,大概率是文件读取问题——比如文件太大、被其他进程占用,或者文件路径是虚拟路径(比如MediaStore的uri,不是真实文件路径)。

5. 用极简代码测试

写个最基础的上传测试,排除业务代码干扰:

void testSimpleUpload() async {
  final dio = Dio();
  final testFile = File("/sdcard/test.png"); // 换成你手机里存在的文件路径
  final formData = FormData.fromMap({
    "file": await MultipartFile.fromFile(testFile.path, filename: "test.png"),
  });
  try {
    final response = await dio.postUri(
      Uri.parse("你的上传接口地址"),
      data: formData,
      options: Options(contentType: Headers.multipartFormDataContentType),
    );
    print("上传成功: ${response.data}");
  } catch (e) {
    print("上传失败: $e");
  }
}

如果这个测试能正常发起请求,说明问题出在你的DTO或者业务逻辑里;如果还是不行,可能是Dio和Android SDK35的兼容性问题,试试降级Dio到5.6.0,或者升级到最新稳定版,另外如果是http接口,要在AndroidManifest.xml里开启android:usesCleartextTraffic="true"。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:50:57