Dart HttpClient无法读取完整响应

问题描述 投票:0回答:1

我在使用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的配置不正确。

flutter dart
1个回答
0
投票

问题是您的响应将按流分批传递。在将这些块传递给utf8解码器之后,您应该将它们形成单个字符串,然后再尝试对其进行json解码。当前,您尝试对第一个块进行json解码,而无需等待其余的块。

package:http的使用要容易得多,它是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
© www.soinside.com 2019 - 2024. All rights reserved.