Flutter调用API获取数据填充Dropdown下拉菜单报错如何解决
问题修复方案
核心问题说明
- XMLHttpRequest错误:你当前是在Flutter Web环境调试,该报错为浏览器跨域CORS限制导致,解决方案有两个:要么后端接口添加允许跨域的响应头,要么本地调试时启动禁用CORS的Chrome环境。
- JSON解析错误:你代码中存在多处异步逻辑、解析逻辑、参数匹配错误,是该报错的直接原因:
getSWData是异步方法,直接调用.toString()拿到的是Future实例的描述字符串,不是接口返回的JSON内容- 接口返回的是纯Event数组,你定义的
Welcome外层结构和实际返回不匹配,解析逻辑完全错误 - 网络请求写在build方法里会被多次触发,不符合开发规范
- Dropdown的
value字段你赋值为活动短标题,但是下拉项的value是活动ID,类型不匹配会触发选择报错
修复后实现代码
// 保留原有Event类即可,Welcome类可以删除,和接口返回结构不匹配 class Test2 extends StatefulWidget { const Test2({Key? key}) : super(key: key); @override _Test2State createState() => _Test2State(); } class _Test2State extends State<Test2> { late Future<List<Event>> _eventFuture; String? selectedEventId; @override void initState() { super.initState(); // 网络请求放在初始化里只触发一次 _eventFuture = getSWData(); } Future<List<Event>> getSWData() async { var res = await http.get(Uri.parse("替换为你的实际接口地址")); // 接口返回直接是Event数组,直接解析即可 List<dynamic> resBody = json.decode(res.body); return resBody.map((item) => Event.fromJson(item)).toList(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ // 用FutureBuilder处理异步加载 FutureBuilder<List<Event>>( future: _eventFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } if (snapshot.hasError) { return Text("加载失败:${snapshot.error}"); } List<Event> events = snapshot.data!; // 默认选中第一个的ID selectedEventId ??= events.first.idEvenement; return DropdownButtonHideUnderline( child: DropdownButton<String>( hint: const Text("Select Region"), value: selectedEventId, isDense: true, onChanged: (String? newValue) { setState(() { selectedEventId = newValue; }); print("选中的活动ID:$selectedEventId"); }, items: events.map((Event event) { return DropdownMenuItem<String>( value: event.idEvenement, child: Text(event.titreCourtEvenement, style: const TextStyle(color: Colors.black)), ); }).toList(), ), ); }, ), ], ), ), ); } }
本地调试跨域问题临时解决方案
如果你是Windows环境,在Flutter Web调试时可以用以下命令启动,禁用浏览器CORS校验:
flutter run -d chrome --web-browser-flag "--disable-web-security"
如果是Mac环境,执行以下命令启动禁用CORS的Chrome:
open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
然后再运行Flutter Web调试即可。
内容的提问来源于stack exchange,提问作者Charles
相关产品推荐
相关产品推荐

