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

Flutter Web中如何监听StreamedResponse的上传进度?

解决MultipartRequest上传进度监听问题

你原来的代码监听的是send()返回的服务器响应流,自然拿不到上传进度。要获取上传过程的字节统计,得直接拦截上传的请求数据流,具体做法如下:

核心思路

MultipartRequest的send()方法内部会先把请求数据序列化为字节流,再发送给服务器。我们需要在这个字节流发送前包装一层,统计每一段发送的字节数,以此计算上传进度。

实现代码

// 1. 初始化MultipartRequest(保留你的原有配置)
final requestMultiPart = http.MultipartRequest(
  'POST',
  Uri.parse('你的上传接口地址'),
);
// 添加上传文件、表单字段等(你的原有逻辑)
requestMultiPart.files.add(await http.MultipartFile.fromPath('file', '本地文件路径'));

// 2. 获取请求的原始字节流和总长度
final requestStream = requestMultiPart.finalize();
final totalUploadBytes = requestMultiPart.contentLength ?? 0;
int uploadedBytes = 0;

// 3. 包装流,注入进度统计逻辑
final progressTrackingStream = requestStream.transform(
  StreamTransformer<List<int>, List<int>>.fromHandlers(
    handleData: (chunk, sink) {
      // 累加已上传字节数
      uploadedBytes += chunk.length;
      // 计算进度(处理总长度为0的异常场景)
      final progress = totalUploadBytes > 0 ? uploadedBytes / totalUploadBytes : 0;
      
      // 更新UI或打印进度
      setState(() {
        _progress = progress;
        print('上传进度:${(progress * 100).toStringAsFixed(2)}%');
      });
      
      // 转发字节块,不影响正常上传流程
      sink.add(chunk);
    },
  ),
);

// 4. 使用http.Client发送包装后的请求
final client = http.Client();
final streamedRequest = http.StreamedRequest(
  requestMultiPart.method,
  requestMultiPart.url,
)
  ..headers.addAll(requestMultiPart.headers)
  ..contentLength = totalUploadBytes
  ..sink.addStream(progressTrackingStream)
  ..sink.close();

// 5. 发送请求并处理服务器响应
final response = await client.send(streamedRequest);
// 可按需将响应流转为字符串或其他格式
final responseBody = await response.stream.bytesToString();
print('服务器响应:$responseBody');

// 关闭客户端释放资源
client.close();

关键说明

  • finalize()方法返回的是MultipartRequest序列化后的请求字节流,这就是要上传给服务器的原始数据。
  • contentLength是请求的总字节数,用来计算进度比例;如果为null(比如无法提前计算长度),可以降级为只显示“上传中”状态。
  • 用StreamTransformer包装流不会中断原有上传逻辑,只是在每个字节块发送前做一次统计,不影响上传效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:24:55