Flutter使用Uri.http发GET请求时queryParameters非字符串值报错问题
问题根本原因
Dart 中 Uri.http 和 Uri.https 构造方法的 queryParameters 参数,官方规定值仅支持两种类型:
- 单个
String/null类型 - 元素为
String/null的Iterable类型
你传入 double、bool 这类非字符串原生类型时,虽然因为你声明了 Map<String, dynamic> 编译期不会报错,但运行时Uri内部做查询参数序列化时会直接抛出类型不匹配异常,这就是你打印Uri的代码不执行的原因:构造Uri的步骤已经崩溃走不到后续逻辑。
为什么全字符串参数能正常运行
HTTP协议中的GET请求查询参数本身就是纯字符串格式传输的,没有原生的数字、布尔类型标识,服务端收到的所有查询参数默认都是字符串格式,需要自行做类型解析。你手动把所有参数转成字符串的操作,正好符合Uri的参数要求,所以可以正常发起请求。
优化方案
方案1:保留现有处理逻辑(推荐)
你当前手动将非字符串参数转成字符串、同时适配Node端解析逻辑的处理是完全合理的,属于HTTP请求处理的常规实践,不需要额外修改。
方案2:封装通用参数转换工具
如果不想每次手动写toString(),可以封装一个通用的参数转换方法,自动把动态Map转成符合Uri要求的参数格式,示例代码如下:
Map<String, dynamic> convertQueryParams(Map<String, dynamic> originParams) { final Map<String, dynamic> processed = {}; originParams.forEach((key, value) { if (value is String || value is Iterable<String?>) { processed[key] = value; } else if (value is num || value is bool) { processed[key] = value.toString(); } else if (value == null) { processed[key] = null; } else { // 其他自定义类型可以在这里补充转换逻辑 processed[key] = value.toString(); } }); return processed; }
使用时直接传入转换后的参数即可:
final Uri uri = UniversalPlatform.isWeb ? Uri.http(Environment.dbUrl, '/api/routes', convertQueryParams(queryParameters)) : Uri.https(Environment.dbUrl, '/api/routes', convertQueryParams(queryParameters));
内容的提问来源于stack exchange,提问作者Vincenzo
相关产品推荐
相关产品推荐

