flutter - Dart HttpClient 未读取完整响应
问题描述
我在使用 dart HttpClient 时遇到了一个奇怪的问题,它似乎在“完成”之前没有读取完整的响应。这是我的代码:
HttpClient client = new HttpClient();
client.connectionTimeout = Duration(seconds: 60);
Completer<MealPlan> completer = new Completer();
RecipeSearchFilter filter = new RecipeSearchFilter();
filter.restrictions = intolerances.map((intolerance) => intolerance.name).toList();
MealPlan mealPlan;
client
.getUrl(Uri.parse(
"https://myUrl.com/api/meal-plans?filter=${jsonEncode(filter)}"))
.then((HttpClientRequest request) {
request.headers.set("Authorization", "Bearer $idToken");
return request.close();
}).then((HttpClientResponse response) {
response.transform(utf8.decoder).listen((contents) {
Map<String, dynamic> contentMap = jsonDecode(contents);
mealPlan = MealPlan.fromJson(contentMap);
}, onDone: () => completer.complete(mealPlan));
});
return completer.future;
这是我的应用程序包含的最密集的功能,因此这个特定的 API 本身通常需要 6-8 秒才能完全完成,因为幕后发生了很多事情。响应不大(~60KB)。使用 Postman 进行完全相同的调用,我可以看到它确实按预期返回了所有内容,但是如果我查看}).then((HttpClientResponse response) {
块内的响应,它只包含非常小的部分响应。我不确定我在这里做错了什么,但我猜我已经错误地配置了 HttpClient 。
解决方案
问题是您的响应将由流分段传递。在通过 utf8 解码器传递这些块之后,您应该在尝试对其进行 json 解码之前将它们形成一个字符串。目前,您尝试 json 解码第一个块而不等待其余部分。
package:http
使用which 包装器要容易得多HttpClient
,并且可以为您完成很多繁重的工作。此外,使用async/await
语法而不是.then
.
使用async
您可以编写的方法,例如:
void getPlan(Map filter, String idToken) async {
var response = await http.get(
Uri.parse('https://myUrl.com/api/meal-plans?filter=${jsonEncode(filter)}'),
headers: <String, String>{
'Authorization': 'Bearer $idToken',
},
);
return MealPlan.fromJson(json.decode(response.body));
}
如果真的要控制连接超时,需要自己传入HttpClient
,如下:
var client =
http.IOClient(HttpClient()..connectionTimeout = Duration(seconds: 60));
var response = await client.get(
//etc
推荐阅读
- android - 我可以在安卓手机响铃时获得音量调高或调低的事件吗?
- rest - 如何在 REST Assured 中发送带有 Authentication 标头的 GET 请求?
- javascript - 通过标签和JS删除样式
- c++ - 密码过期时通过 ODBC 连接到 Oracle
- c# - Mono - 类型“对象”在未引用的程序集中定义
- javascript - 在反应应用程序中找不到 bundlel.js 页面
- docker - 是否可以在 Docker 上运行多个容器来运行公共服务?
- css - CSS Float - 清除具有固定位置的两个 div
- perl - 如何修复未定义的子例程主要错误
- c# - 将 WinForm 应用程序转换为命令行?