You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:33:25