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

Flutter中API GET请求阻塞问题求助

解决Flutter GET请求阻塞问题

1. 修复请求地址的协议与本地访问问题

你的请求地址localhost:8082/appointments存在两个关键问题:缺少http/https协议前缀,且在Flutter设备(模拟器/真机)中,localhost指向设备自身而非运行后端的电脑,直接导致请求无法到达本地服务。

修改方案:

  • 强制添加协议前缀http://
  • 根据运行环境替换地址:
    • Android模拟器:用10.0.2.2代替localhost(Android模拟器专属映射地址,指向宿主机)
    • iOS模拟器:可直接使用localhost
    • 真机/局域网测试:替换为电脑的局域网IP(如192.168.1.100)

修改后的DoctorService代码:

class DoctorService {
  // 根据运行环境选择对应地址
  final String appointmentURL = 'http://10.0.2.2:8082/appointments'; // Android模拟器
  // final String appointmentURL = 'http://localhost:8082/appointments'; // iOS模拟器
  // final String appointmentURL = 'http://192.168.1.100:8082/appointments'; // 真机/局域网

  Future<List<Doctor>> getDoctors() async {
    print("TEST");
    var res = await get(Uri.parse(appointmentURL));
    print("TEST2");

    if (res.statusCode == 200) {
      final obj = jsonDecode(res.body);
      // 补充Doctor模型的反序列化逻辑
      List<Doctor> doctors = (obj as List).map((item) => Doctor.fromJson(item)).toList();
      return doctors;
    } else {
      throw Exception("请求失败,状态码:${res.statusCode}");
    }
  }
}

2. 检查并添加网络权限

Android端

在android/app/src/main/AndroidManifest.xml中添加网络权限,放在<application>标签之前:

<uses-permission android:name="android.permission.INTERNET"/>

iOS端

若使用http协议(非https),需在ios/Runner/Info.plist中添加非安全域名允许配置:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

注意:上线版本建议改用https协议,移除该配置。

3. 优化FutureBuilder使用(避免重复请求)

当前在build方法中直接调用doctorService.getDoctors(),会导致组件每次重建都触发新请求,建议在initState中初始化Future:

class _DoctorSelectionScreen extends State<DoctorSelectionScreen> {
  DoctorService doctorService = DoctorService();
  late Future<List<Doctor>> _doctorsFuture;

  @override
  void initState() {
    super.initState();
    _doctorsFuture = doctorService.getDoctors(); // 仅初始化时请求一次
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        drawer: const NavigationDrawerWidget(),
        appBar: AppBar(backgroundColor: Colors.green, title: const Text("Doctors")),
        body: FutureBuilder(
            future: _doctorsFuture,
            builder: (BuildContext context, AsyncSnapshot<List<Doctor>> snapshot) {
              if (snapshot.hasData) {
                List<Doctor>? doctors = snapshot.data;
                return Column(children: <Widget>[
                  for (var doctor in doctors!) buildDoctor(doctor)
                ]);
              } else if (snapshot.hasError) {
                return Center(child: Text("请求错误:${snapshot.error}")); // 显示错误信息便于排查
              } else {
                return const Center(child: CircularProgressIndicator()); // 加载状态提示
              }
            }),
      ),
    );
  }
}

4. 补充错误排查步骤

  • 执行flutter clean后重新构建项目,清除缓存问题
  • 确认后端服务确实在8082端口运行,且本地防火墙未拦截该端口
  • 在getDoctors中捕获异常并打印详细信息:
Future<List<Doctor>> getDoctors() async {
  print("TEST");
  try {
    var res = await get(Uri.parse(appointmentURL));
    print("TEST2");
    print("响应状态码:${res.statusCode}");
    if (res.statusCode == 200) {
      final obj = jsonDecode(res.body);
      List<Doctor> doctors = (obj as List).map((item) => Doctor.fromJson(item)).toList();
      return doctors;
    } else {
      throw Exception("请求失败,状态码:${res.statusCode}");
    }
  } catch (e) {
    print("请求异常:$e");
    throw e;
  }
}

内容的提问来源于stack exchange,提问作者lw00

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:05:18