Flutter调用http.post传递List<String>参数报类型转换错误的解决方法
Dart官方http包的post方法默认走application/x-www-form-urlencoded表单编码,该模式强制要求请求体是Map<String, String>类型,所有参数值必须是字符串格式。
你直接把List<String>类型的_selectedItems作为Map的value传入,不符合类型要求,编码阶段自然就抛出type 'List<String>' is not a subtype of type 'String' in type cast的类型转换错误。
另外你的代码有个不规范的细节:方法参数和类的私有成员变量同名(都用_selectedItems命名),会造成变量作用域遮蔽,虽然不是报错的直接原因,但很容易引发逻辑偏差,建议把方法参数改成不带私有前缀的selectedItems。
根据后端接口的实际接收能力,选对应的实现方式即可:
方案1:JSON格式传参(推荐,兼容性最好)
手动指定请求体为JSON格式,JSON天然支持列表、嵌套对象这类复杂结构,前后端适配成本最低:
- 手动设置请求头为JSON格式
- 用
jsonEncode把包含列表的请求体序列化为标准JSON字符串
import 'dart:convert'; Future<void> _filterItem(List<String> selectedItems) async { ProgressDialog pr = ProgressDialog(context, type: ProgressDialogType.Normal, isDismissible: false); pr.style(message: "Loading..."); await pr.show(); try { final res = await http.post( Uri.parse("https://one.com/myapp/php/load_data.php"), headers: {"Content-Type": "application/json"}, body: jsonEncode({ "_selectedItems": selectedItems, }), ); if (res.body == "nodata") { setState(() { print("No Found"); }); } else { setState(() { var extractdata = json.decode(res.body); tutordata = extractdata["mydata"]; }); } } catch (err) { print(err); } finally { // 不管请求成功、失败都确保弹窗被关闭 await pr.hide(); } }
后端适配提示:PHP端接收JSON格式请求时,不能直接从
$_POST取参数,通过json_decode(file_get_contents('php://input'), true)读取原始请求体,就能直接拿到_selectedItems对应的数组值。
方案2:传统表单格式传参(适配不支持JSON的老接口)
如果后端只能接收application/x-www-form-urlencoded的传统表单,不能直接传List,最简单的适配方式是把列表用固定分隔符(比如逗号)拼接成单个字符串传给后端,后端接收后再拆分回数组:
http.post( Uri.parse("https://one.com/myapp/php/load_data.php"), body: { // 用逗号把列表拼接为可传输的字符串 "_selectedItems": selectedItems.join(","), }, );
后端适配提示:PHP端拿到
$_POST['_selectedItems']后,用explode(',', $_POST['_selectedItems'])就能还原为数组正常使用。
内容的提问来源于stack exchange,提问作者KAR Shinyong

