如何在Dart http库的Multipart POST请求中设置多值表单与文件字段?
问题根源
request.fields是Map<String, String>类型,键唯一,调用addEntries时同名字段后面的会直接覆盖前面的,导致请求里只发送了最后一个organs值,不符合接口入参要求。request.files本身是List<MultipartFile>结构,原生支持添加多个同名字段,你原来的文件处理逻辑没有问题,不需要调整。
解决方法
多值同名字段不能走 request.fields 添加,需要把每个文本字段用 http.MultipartFile.fromString 构造为文本类型的 multipart part,直接添加到 request.files 列表中即可。
修改后的完整代码
// 前置依赖导入参考: // import 'package:http/http.dart' as http; // import 'dart:convert'; // import 'dart:io'; // import 'package:path/path.dart' as p; static Future<T> postFilesAndGetJson<T>(String url, { List<MapEntry<String, String>> paths, List<MapEntry<String, String>> fields }) async { var request = http.MultipartRequest('POST', Uri.parse(url)); // 处理多值文件字段(原有逻辑保留即可) if (paths != null && paths.isNotEmpty) { paths.forEach((path) { var file = File.fromUri(Uri.parse(path.value)); var multipartFile = http.MultipartFile.fromBytes( path.key, file.readAsBytesSync(), filename: p.basename(file.path) ); request.files.add(multipartFile); }); } // 处理多值文本字段,替换原有addEntries逻辑 if (fields != null && fields.isNotEmpty) { fields.forEach((field) { // 构造文本类型的multipart part,直接添加到files列表 var textPart = http.MultipartFile.fromString( field.key, field.value, ); request.files.add(textPart); }); } return http.Response .fromStream(await request.send()) .then((response) { if (response.statusCode == 200) { return jsonDecode(response.body) as T; } print('Status Code : ${response.statusCode}...'); return null; }); }
对应你给出的curl场景的调用方式
await postFilesAndGetJson( "https://my-api.plantnet.org/v2/identify/all?api-key=11111111111111111111", // 多值文件字段,两个同key的images条目 paths: [ MapEntry("images", "images/image_1.jpeg"), MapEntry("images", "images/image_2.jpeg"), ], // 多值文本字段,两个同key的organs条目 fields: [ MapEntry("organs", "flower"), MapEntry("organs", "leaf"), ], );
补充说明
- 如果确定某个字段是单值,依然可以用
request.fields直接赋值,写法更简洁。 http.MultipartFile.fromString默认使用text/plain的Content-Type,符合multipart/form-data规范,不需要额外指定配置。
内容的提问来源于stack exchange,提问作者Ουιλιαμ Αρκευα
相关产品推荐
相关产品推荐

