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
相关产品推荐
相关产品推荐

