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监听,确认方法是否被调用:
如果打印了日志但拦截器没触发,说明请求在Dio内部卡住了,大概率是文件读取问题——比如文件太大、被其他进程占用,或者文件路径是虚拟路径(比如MediaStore的uri,不是真实文件路径)。final cancelToken = CancelToken(); print("准备发起上传请求"); final result = await upload( uri: yourUploadUri, data: formData, options: Options(contentType: Headers.multipartFormDataContentType), );
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
相关产品推荐
相关产品推荐

