API调用成功后FutureBuilder未完成加载的问题排查
问题分析与修复
你的核心问题是错误地将http.Response对象直接传入jsonDecode:post()函数返回的是Future<http.Response>,所以snapshot.data是http.Response实例,不是响应体字符串,必须先提取response.body再进行JSON解码。同时原代码缺少错误处理和响应状态校验,也会导致异常后无法正常反馈状态。
修复后的完整代码
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; class LeadsList extends StatelessWidget { LeadsList({Key? key}) : super(key: key); // 将Future存储为成员变量,避免build方法重复触发API调用 final Future<http.Response> _fetchLeads = post(); @override Widget build(BuildContext context) { return FutureBuilder( future: _fetchLeads, builder: (BuildContext context, AsyncSnapshot<http.Response> snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 请求出错状态 if (snapshot.hasError) { return Center(child: Text('请求出错: ${snapshot.error}')); } // 确保数据存在且响应状态码正常 if (snapshot.hasData) { final response = snapshot.data!; // 校验HTTP状态码,确保请求真正成功 if (response.statusCode == 200) { try { final list = jsonDecode(response.body); final responseData = list["response"]; // 处理空数据情况 if (responseData == null || responseData.isEmpty) { return const Center(child: Text('暂无数据')); } return ListView.builder( itemCount: responseData.length, itemBuilder: (context, index) { return Card( child: Padding( padding: const EdgeInsets.all(8.0), child: Text(responseData[index]["fullname"] ?? '未知名称'), ), ); }, ); } catch (e) { return Center(child: Text('数据解析失败: $e')); } } else { return Center(child: Text('请求失败,状态码: ${response.statusCode}')); } } // 兜底状态 return const Center(child: Text('未知状态')); }, ); } } Future<http.Response> post() { return http.post( Uri.parse('https://api_url.link'), headers: {'Content-Type': 'application/json'}, // POST JSON需添加此请求头 body: jsonEncode({ // JSON参数 }), ); }
关键修复点
- 正确提取响应体:使用
response.body获取API返回的字符串后,再传入jsonDecode处理 - 缓存Future对象:将
post()结果存储为成员变量,避免build方法重复触发API调用 - 完善状态处理:
- 明确判断
ConnectionState.waiting作为加载状态 - 处理
snapshot.hasError的错误场景 - 校验HTTP响应状态码(如200),确保请求真正成功
- 添加JSON解析异常捕获,避免崩溃
- 处理空数据或字段缺失的情况(如
fullname为null时显示默认值)
- 明确判断
- 补充请求头:POST JSON数据时,必须设置
Content-Type: application/json头,部分API会因此拒绝请求
内容的提问来源于stack exchange,提问作者angel
相关产品推荐
相关产品推荐

