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

Dart HTTP客户端/Dio请求无限加载无响应,无报错问题求助

问题原因排查与修复方案

核心问题定位

  • 缺失全局异常捕获:Timer.periodic回调中的异步异常默认不会输出到控制台,你没有给send请求、stream监听逻辑添加try-catch,所有连接阶段、请求阶段的错误都被静默吞掉,所以看不到任何报错。
  • 超时配置覆盖不全:你添加的.timeout(Duration(seconds: 45))仅作用于请求发送后等待响应的阶段,没有覆盖DNS解析、TCP连接建立的阶段,若请求在连接建立阶段被拦截(比如云服务商安全组规则变更、目标服务器静默丢弃连接包),就会出现永久卡住、超时不生效的问题。
  • 资源泄漏隐患:每次refresh调用都新建Client实例但未调用.close()释放连接,多次调用后会耗尽服务器出站连接配额,导致新请求无法建立连接。
  • 全局变量未重置:你代码中用到的bytes全局变量没有在每次请求前初始化,若上一次请求残留了数据,也可能引发不可预期的IO异常。

具体调试步骤

  1. 补全全链路异常捕获,所有异步操作都用try-catch包裹,打印错误栈信息
  2. 开启Dart HTTP调试日志,在程序入口添加如下代码,输出连接全链路状态:
import 'dart:io';
// 开启内置HttpClient日志
HttpClient.enableTimelineLogging = true;

如果用Dio的话直接添加LogInterceptor即可打印DNS解析、连接建立、请求发送每个阶段的状态。
3. 在Ubuntu服务器上执行抓包验证请求是否发出:

# 替换为你目标文件的域名和端口,HTTPS用443,HTTP用80
tcpdump -i any host [目标域名] and port 443

运行Dart服务后对比curl请求和Dart请求的抓包结果,确认Dart有没有成功发出连接请求。
4. 检查运行环境差异:确认运行Dart服务的系统用户和测试curl的用户是否一致,有没有用户级别的HTTP_PROXY/HTTPS_PROXY环境变量配置差异。

修复后代码参考

import 'dart:async';
import 'dart:io';
import 'package:http/http.dart';

final articlesUrl = "你的实际CSV地址";

void refreshData() {
  Future<void> refresh() async {
    print('refreshing data...');
    List<int> bytes = []; // 每次请求重置bytes,不要用全局变量
    Client? client;
    try {
      client = Client();
      // 分阶段设置超时:连接超时+响应超时
      final request = Request('GET', Uri.parse(articlesUrl));
      final response = await client.send(request)
          .timeout(const Duration(seconds: 15), onTimeout: () {
            throw TimeoutException("请求响应超时");
          });
      
      int total = response.contentLength ?? 0;
      int received = 0;
      
      await response.stream.listen((value) {
        bytes.addAll(value);
        received += value.length;
        print('Received: $received of $total');
      }).asFuture().timeout(const Duration(seconds: 30)); // 流接收也加超时
      
      await File('assets/data/articles.csv').writeAsBytes(bytes);
      print('file written.');
    } catch (e, stackTrace) {
      // 打印所有错误和栈信息
      print("请求出错: $e");
      print("错误栈: $stackTrace");
    } finally {
      client?.close(); // 无论成功失败都关闭client释放连接
    }
  }

  // 首次调用也要捕获异常
  unawaited(refresh());
  const timer = Duration(minutes: 30);
  Timer.periodic(timer, (Timer t) async {
    await refresh();
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:15:05