Flutter使用Dio提交FormData携带文件参数返回501错误如何解决?
问题原因及修复方案
错误点梳理
- 文件列表构造错误:
forEach方法无返回值,你将forEach的执行结果塞入files数组,最终files字段实际为[null],没有正确传递文件数据。 - 复合参数强转错误:
scheduled_slots是List<Map>类型,直接使用as String强转会抛出类型转换异常,实际传递到后端的参数值无效。 - 数组参数格式不匹配:普通数组
type、rating直接传入FormData时,默认序列化格式可能和后端要求的解析规则不匹配。
修复后代码
import 'dart:convert'; import 'package:dio/dio.dart'; Dio dio = Dio(); // 添加日志拦截器,可打印完整请求参数,方便和Postman参数对比排查 dio.interceptors.add(LogInterceptor( requestBody: true, responseBody: true, requestHeader: true )); List<Map<String, int>> scheduled_slots = [ {"dateslot_id": 107, "timeslot_id": 97}, {"dateslot_id": 121, "timeslot_id": 120} ]; List<String> filesPath = ["/data/user/0/com.heckerbella.hope_clinic/app_flutter/1634521427103972"]; List<String> filesName = ["fileName"]; List<String> type =["Burning Pain", "Burning Pain"]; List<String> rating =["Just curious", "Mild Pain"]; // 正确构造多文件列表 final multipartFiles = await Future.wait(filesPath.asMap().entries.map((entry) async { final index = entry.key; return await MultipartFile.fromFile(entry.value, filename: filesName[index]); })); FormData formData = FormData.fromMap({ "type": type, "rating": rating, "description": widget.description, "files": multipartFiles, // 复合类型序列化为JSON字符串传递,若后端要求form数组格式可自行调整为打散传参 "scheduled_slots": jsonEncode(scheduled_slots), }, // 配置数组序列化格式,和Postman传参格式对齐即可,可选值:multiCompatible、brackets、repeat、csv listFormat: ListFormat.multiCompatible ); try { Response response = await dio.post( Constants().API_BASE_URL + "scheduled/slot/main/create/${selectedPlansData.id}", data: formData, options: Options(responseType: ResponseType.json, headers: { "Authorization": "Bearer ${bloc.bearerToken}", "Accept": "application/json", })); AlertManager.showToast(response.data.toString()); print(Constants().API_BASE_URL + "scheduled/slot/main/create/${selectedPlansData.id}"); return response.data; } catch (e) { print(e.toString()); }
补充说明
如果修改后仍报错,可对比日志拦截器输出的请求参数和Postman的请求体,确保参数名、参数格式完全一致即可。
内容的提问来源于stack exchange,提问作者Ben Ajax
相关产品推荐
相关产品推荐

