【问题标题】:How to cancel ongoing file upload sent with http.MultipartRequest() in Flutter?如何取消在 Flutter 中使用 http.MultipartRequest() 发送的正在进行的文件上传?
【发布时间】:2019-01-03 07:59:14
【问题描述】:

我正在尝试在我的 Flutter 应用中为文件上传添加取消功能。我目前正在使用来自http packagehttp.MultipartRequest() 来上传文件。我尝试使用 CancelableOperation 打包上传,但它只会取消我的 Flutter 应用程序中的内部进程,并且文件仍会成功上传到我的 Firebase 存储服务器。

我阅读了关于使用http.Client() 并在http 请求完成后关闭它的http 包上的README.md。我正在考虑使用http.Client() 上传文件,然后用http.Client().close() 关闭它以取消http 请求。

但是,我还没有找到使用http.Client 上传文件的正确方法。我在 Google 和 stackoverflow 上浏览过它,但所有帖子都建议使用 http.MultipartRequest()One of the posts

所以,我的问题是: 1. Flutter中的http包可以取消http.MultipartRequest()发送的上传文件吗? 2.我是否在尝试使用http.Client() 的正确轨道上?或者有没有更好的方法来做到这一点? 3.如果使用http.Client()是唯一的方法,那么你能告诉我如何使用http.Client()上传文件吗?因为它只有post() 而没有multipartrequest()

抱歉,文字太长了。请帮忙。谢谢!

【问题讨论】:

  • 嗨,我尝试使用http.Client.close(),但它确实取消了我的发布 http 请求。所以,我现在需要的是如何使用http.Client.post() 上传文件。任何帮助将非常感激。谢谢!

标签: http file-upload dart flutter


【解决方案1】:

http 在引擎盖下使用HTTPClient。它将底层客户端包装在IOClient 中。大多数http 的方法(如getpost)允许您传入自己的客户端,但MultipartRequest 不允许(它为每个请求创建一个)。

最简单的解决方案似乎是对其进行子类化。

import 'dart:async';
import 'dart:io';

import 'package:http/http.dart' as http;

class CloseableMultipartRequest extends http.MultipartRequest {
  http.IOClient client = http.IOClient(HttpClient());

  CloseableMultipartRequest(String method, Uri uri) : super(method, uri);

  void close() => client.close();

  @override
  Future<http.StreamedResponse> send() async {
    try {
      var response = await client.send(this);
      var stream = onDone(response.stream, client.close);
      return new http.StreamedResponse(
        new http.ByteStream(stream),
        response.statusCode,
        contentLength: response.contentLength,
        request: response.request,
        headers: response.headers,
        isRedirect: response.isRedirect,
        persistentConnection: response.persistentConnection,
        reasonPhrase: response.reasonPhrase,
      );
    } catch (_) {
      client.close();
      rethrow;
    }
  }

  Stream<T> onDone<T>(Stream<T> stream, void onDone()) =>
      stream.transform(new StreamTransformer.fromHandlers(handleDone: (sink) {
        sink.close();
        onDone();
      }));
}

【讨论】:

  • 非常感谢@Richard Heap,它就像一个魅力!谢谢你花时间给我这么详细的回答。我真的很感激:)
  • @Richard 如果使用 CloseableMultipartRequest 的每个新实例重新创建 http 客户端,则此解决方案有效。但是,它不支持对客户端实例的引用,在这种情况下,关闭连接以取消请求并不是一个好主意。
猜你喜欢
  • 2019-05-12
  • 1970-01-01
  • 2018-03-18
  • 2019-09-06
  • 2021-03-20
  • 2012-03-26
  • 2020-09-28
  • 2021-03-13
  • 2020-11-02
相关资源
最近更新 更多