Flutter GetX调用本地Express Node.js API返回null的问题排查
问题
我正在尝试将基于GetX的Flutter前端与Node.js Express框架搭建的API集成,已编写简易Express服务器代码,同时在Flutter项目中通过继承GetConnect的UserRepository调用/users接口。但调用后返回的statusCode和body均为null,使用Postman调用该API正常,Flutter调用公网API(如https://jsonplaceholder.typicode.com/users)也正常,请问错误原因是什么?
Express服务器代码
import express from "express"; import cors from 'cors'; const PORT = 3000; const app = express(); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods", "GET, PUT, PATCH, POST, DELETE"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); app.use(cors({ origin: '*' })); next(); }); app.get('/', (request, response) => { response.status(200).send(JSON.stringify( { message: 'Welcome to API, for test' } )); }); app.get('/users', (req, res) => { console.log(req); const users = [{ id: 1, name: 'Steave Jobs', email: 'jobs@mail.com', }, { id: 2, name: 'Bill Gates', email: 'bill@mail.com', }, { id: 3, name: 'Mark Zuckerberg', email: 'zuck@mail.com', }]; console.log(JSON.stringify(users, null, " ")); res.status(200).send(JSON.stringify(users, null, " ")); }); app.listen(PORT, () => { console.log(`Server inicializated in port ${PORT}`); });
Flutter代码
import 'package:get/get.dart'; import 'package:teste_api/user.model.dart'; class UserRepository extends GetConnect { Future<List<User>> getUsers() async { List<User> users = []; var path = 'http://localhost:3000/users'; print("*********************************************************************"); print(path); print("*********************************************************************"); final response = await get(path); print('STATUS: ${response.statusCode}'); print('RESPONSE: ${response.body}'); print("*********************************************************************"); return users; } }
运行结果
Performing hot reload... Syncing files to device sdk gphone64 x86 64... I/flutter ( 823): ****************************************************************** I/flutter ( 823): http://localhost:3000/users I/flutter ( 823): ****************************************************************** Reloaded 1 of 812 libraries in 1.085ms (compile: 52 ms, reload: 298 ms, reassemble: 295 ms). D/EGL_emulation( 823): app_time_stats: avg=65535.99ms min=48.92ms max=131023.07ms count=2 I/flutter ( 823): STATUS: null I/flutter ( 823): RESPONSE: null I/flutter ( 823): ******************************************************************
问题分析与解决
1. 核心原因:模拟器/真机的localhost指向错误
在Android模拟器中,localhost指向的是模拟器自身的本地网络,而非运行Express服务器的电脑。这会导致Flutter应用无法连接到电脑上的API服务,请求直接失败,所以返回的statusCode和body都是null。
解决方法:
- 若使用Android模拟器,将请求地址替换为
http://10.0.2.2:3000/users(10.0.2.2是Android模拟器预留的、映射到电脑localhost的特殊IP)。 - 若使用真机或iOS模拟器,换成电脑的局域网IP地址(比如
http://192.168.x.x:3000/users,可通过ipconfig(Windows)或ifconfig(Mac/Linux)查看)。
2. 次要问题:Express的CORS配置重复冲突
代码中同时手动设置了CORS响应头,又调用了cors中间件,可能导致CORS规则冲突,虽然Postman能正常请求,但部分客户端可能出现异常。
优化方法:
删除手动设置的header代码,只保留cors中间件配置,简化为:
import express from "express"; import cors from 'cors'; const PORT = 3000; const app = express(); // 只保留cors中间件即可 app.use(cors({ origin: '*', methods: ["GET", "PUT", "PATCH", "POST", "DELETE"], allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept"] })); // 后续路由代码不变...
3. 补充:添加错误捕获排查问题
在Flutter代码中添加try-catch,可以捕获请求失败的具体异常信息,方便排查:
Future<List<User>> getUsers() async { List<User> users = []; var path = 'http://10.0.2.2:3000/users'; print("*********************************************************************"); print(path); print("*********************************************************************"); try { final response = await get(path); print('STATUS: ${response.statusCode}'); print('RESPONSE: ${response.body}'); // 可以在这里处理响应数据,比如转成User列表 if(response.statusCode == 200) { users = (response.body as List).map((e) => User.fromJson(e)).toList(); } } catch(e) { print('请求异常: $e'); // 打印具体错误信息 } print("*********************************************************************"); return users; }
内容的提问来源于stack exchange,提问作者Fabiano Castro Monteiro
相关产品推荐
相关产品推荐

