我正在尝试在我的 Flutter 应用中添加取消文件上传功能。我目前正在使用 http package
中的 http.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()
。
抱歉,文字太长了。请帮忙。谢谢!
最佳答案
Package http
在底层使用了 HTTPClient
。它将底层客户端包装在 IOClient
中。 http
的大多数方法(如 get
和 post
)都允许您传入自己的客户端,但是 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();
}));
}
关于http - 如何取消在 Flutter 中使用 http.MultipartRequest() 发送的正在进行的文件上传?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54018383/