You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Uri.resolve解析HTTPS地址iOS与Android表现不一致

Flutter 跨平台Uri.resolve路径丢失问题原因与解决方案

核心原因

该问题和DIO库无关,本质是Flutter 2.10.5稳定版中,Uri类的解析逻辑存在平台实现差异,iOS端会隐式裁剪基础URL路径末尾的斜杠,导致相对路径拼接规则触发异常。

差异触发原理

URL相对路径拼接遵循RFC 3986标准,规则非常明确:

  • 若基础URL的路径以/结尾,调用resolve()传入相对路径时,会将相对路径直接追加到当前路径末尾
  • 若基础URL的路径不以/结尾,调用resolve()传入相对路径时,会将路径最后一个斜杠后的内容替换为相对路径

两个平台的实现差异点:

  • Android端使用Dart VM内置的纯Dart实现的Uri解析逻辑,会完整保留配置的https://best-service-ever.com/access/原始路径,识别为/access/(末尾带斜杠),因此拼接login时得到/access/login,符合预期。
  • iOS端在该版本Flutter中,Uri解析底层调用系统原生CFURL能力,原生层会自动对URL做规范化处理,隐式裁剪掉路径末尾的孤立斜杠,Uri.parse执行完成后,拿到的路径已经变成/access(无末尾斜杠),此时拼接login就会把最后一段access替换为login,最终得到丢失/access段的错误地址。

适配方案(满足基础地址复用约束)

不需要修改settings配置文件中的原始URL,也不需要硬编码access/login这类固定拼接路径,只需要在生成firstUri时显式校验并补全路径末尾斜杠,绕开iOS端的自动裁剪逻辑即可,所有复用该基础地址的逻辑都不会受影响:

static Uri get firstUri {
  final rawUri = Uri.parse(settings.firstUrl);
  // 显式保证路径以斜杠结尾,统一全平台resolve行为
  if (!rawUri.path.endsWith('/')) {
    return rawUri.replace(path: '${rawUri.path}/');
  }
  return rawUri;
}

static Uri get loginUri =>
    firstUri.resolve('login').replace(queryParameters: <String, dynamic>{'service': settings.secondUrl});

该方案对任意基础路径都生效,后续如果调整基础URL的路径值,不需要修改这段适配逻辑。


内容的提问来源于stack exchange,提问作者Piotr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:09:11