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

Flutter如何优化HTTP请求处理 实现请求失败自动重试

问题核心诱因

Postman调试正常但App内请求异常,基本是以下几个原因导致:

  • 移动端系统明文HTTP限制:Android 9(API 28)、iOS 9以上版本默认禁止非HTTPS的明文请求,桌面端Postman不受该系统规则约束,这是最高发的诱因
  • 原有代码逻辑漏洞:
    • 未校验HTTP响应状态码:只要请求未抛出异常就判定连接成功,服务端返回4xx/5xx错误时会误判为连接正常
    • 超时逻辑不完整:仅给Future加了超时约束,未主动终止超时后的后台请求,会造成连接泄漏,积累到一定程度后续所有请求都会卡死
    • 手动配置Keep-Alive头不当:http插件默认会自动管理连接复用规则,手动写死短超时Keep-Alive头反而会导致连接被提前中断
  • 无容错重试机制:偶发的网络波动、连接瞬断就会直接判定为连接失败,也没有任何恢复逻辑
前置配置修复

如果暂时无法将接口切换为HTTPS,需要先放开系统的明文请求限制:

  • Android端:在android/app/src/main/AndroidManifest.xml的<application>标签中添加属性android:usesCleartextTraffic="true"
  • iOS端:在ios/Runner/Info.plist中添加NSAppTransportSecurity配置,放开对应请求域名的明文访问权限
优化后的请求实现(带自动重试)

实现逻辑遵循几个规则:

  • 最多重试3次,避免无限重试导致应用卡死
  • 采用指数退避间隔重试,避免短时间高频请求加剧网络拥堵
  • 区分错误类型:4xx客户端错误(地址错误、参数错误等)不重试,超时、连接中断、5xx服务端错误才触发重试
  • 请求结束主动释放连接资源,避免连接泄漏
  • 严格校验响应状态码,避免误判
import 'dart:async';
import 'package:http/http.dart' as http;

Future<bool> testConnection(String code) async {
  const maxRetryTimes = 3;
  int currentRetry = 0;
  final baseRetryInterval = const Duration(seconds: 1);
  // 独立创建客户端,请求结束统一释放资源
  final requestClient = http.Client();

  try {
    while (true) {
      try {
        final requestUri = Uri.parse("http://$code/Api/public/api/testConnection");
        final response = await requestClient.get(requestUri).timeout(
          const Duration(seconds: 10),
          onTimeout: () {
            // 超时主动抛错,终止当前请求流程
            throw TimeoutException("连接超时");
          },
        );

        // 状态码200-299区间判定为请求成功
        if (response.statusCode >= 200 && response.statusCode < 300) {
          return true;
        }

        // 4xx为客户端错误,无重试必要,直接返回失败
        if (response.statusCode >= 400 && response.statusCode < 500) {
          return false;
        }

        // 其余状态码(主要是5xx服务端错误)进入重试流程
        throw Exception("服务端异常,状态码:${response.statusCode}");
      } catch (e) {
        currentRetry++;
        // 超过最大重试次数直接返回失败
        if (currentRetry > maxRetryTimes) {
          return false;
        }
        // 等待指数间隔后重试
        await Future.delayed(baseRetryInterval * currentRetry);
      }
    }
  } finally {
    // 无论请求成功/失败/超时,都关闭客户端释放连接
    requestClient.close();
  }
}
额外优化建议
  • 生产环境优先将接口切换为HTTPS,既可以规避系统明文限制,也能保证数据传输安全
  • 不要手动添加Keep-Alive等连接管理类请求头,http插件默认的连接池配置已经适配移动端网络场景,手动修改容易引发连接复用异常
  • 页面加载状态必须和请求生命周期绑定:在finally回调中统一关闭加载弹窗/状态,避免请求异常时页面永久卡在加载状态
  • 如果应用存在大量网络请求,建议全局维护单例http.Client,统一配置公共请求头、超时规则,减少频繁创建销毁客户端的性能开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:54:28