如何用Dart以x-www-form-urlencoded格式提交嵌套结构数据?
解决嵌套结构转x-www-form-urlencoded的问题
你的问题出在直接对嵌套的数组/对象调用toString(),这会生成无法被服务端解析的无效字符串(比如[Instance of '_InternalLinkedHashMap<String, dynamic>'])。x-www-form-urlencoded对于嵌套结构需要按照层级键名的格式拼接,比如data[0][prefix]、data[0][phone]这类形式,和Postman里的提交逻辑一致。
下面是正确的递归转换实现:
String encodeNestedMap(Map<String, dynamic> map, [String parentKey = '']) { final parts = <String>[]; map.forEach((key, value) { final currentKey = parentKey.isEmpty ? key : '$parentKey[$key]'; if (value is Map<String, dynamic>) { // 递归处理嵌套Map parts.add(encodeNestedMap(value, currentKey)); } else if (value is List) { // 处理数组,为每个元素添加索引标识 for (var i = 0; i < value.length; i++) { final item = value[i]; if (item is Map<String, dynamic>) { parts.add(encodeNestedMap(item, '$currentKey[$i]')); } else { // 非对象类型的数组元素直接编码 parts.add( '${Uri.encodeQueryComponent('$currentKey[$i]')}=${Uri.encodeQueryComponent(item.toString())}' ); } } } else { // 基础类型直接编码键值对 parts.add( '${Uri.encodeQueryComponent(currentKey)}=${Uri.encodeQueryComponent(value.toString())}' ); } }); return parts.join('&'); } // 使用示例 Map<String, dynamic> body = { 'data': [ { 'prefix': '225', 'phone': '1234567890', 'email': 'test@gmail.com', 'name': 'test', 'surname': 'test', }, ], }; String bodyString = encodeNestedMap(body); // 输出结果:data[0][prefix]=225&data[0][phone]=1234567890&data[0][email]=test%40gmail.com&data[0][name]=test&data[0][surname]=test
原方法失效原因
你之前的代码直接把entry.value(整个数组)转成字符串,得到的是类似[{prefix: 225, phone: 1234567890, ...}]的非标准格式,服务端无法识别。而递归处理会把每个嵌套字段拆成符合x-www-form-urlencoded规范的键值对,完全匹配Postman的提交逻辑。
内容的提问来源于stack exchange,提问作者Kla
相关产品推荐
相关产品推荐

