基于经纬度的Flutter天气应用调用OpenWeatherMap API返回HTML代码而非天气数据的问题求助
问题分析与解决方案
你遇到的核心问题是API请求的URL缺少协议头(https://),导致http.get把它当成了相对路径,最终请求到了Flutter开发服务器的根页面,返回了你看到的HTML代码。另外还有几个小问题需要一起修正,确保功能正常运行:
1. 修复API URL
你的getData方法里的URL没有https://前缀,必须补上:
var url = Uri.parse('https://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=92e463e61258ef5a8b9a9bd11733b62c');
没有协议头的话,http包会默认把这个URL当作当前页面的相对路径(比如你用Flutter Web调试时,就会请求http://localhost:xxxx/api.openweathermap.org/...,而这个路径不存在,服务器就返回了默认的HTML入口文件)。
2. 等待定位完成再请求天气数据
你的getLocation方法里调用ob.getCurrentLocation()时没有用await,这会导致定位操作还没完成,就可能去请求天气数据(如果后续要把获取到的经纬度传给API的话)。修正getLocation:
Future<void> getLocation() async { location ob = location(); await ob.getCurrentLocation(); // 加上await等待定位完成 // 定位完成后再调用getData,还可以把ob的latitude和longitude传进去 getData(ob.latitude, ob.longitude); }
同时修改getData方法,支持传入经纬度:
Future<void> getData(double lat, double lon) async { var url = Uri.parse('https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=92e463e61258ef5a8b9a9bd11733b62c'); var response = await http.get(url); if(response.statusCode==200) { String data = response.body; print(data); } else { print(response.statusCode); print(response.body); // 可以打印错误响应内容,方便排查 } }
3. 避免重复调用getData
你现在在build方法里调用getData,而build会在Widget重建时多次执行(比如屏幕旋转、状态变化),这会导致重复发起API请求。应该把getData的调用移到initState里,或者在定位完成后调用:
@override void initState(){ super.initState(); getLocation(); // 定位完成后会调用getData } @override Widget build(BuildContext context) { return Scaffold( body: Center(child: Text("Loading weather...")), // 可以加个加载提示 ); }
4. 其他小优化
- 你的
location类的成员变量可以加上late修饰符,避免空安全问题:
class location{ late double latitude; late double longitude; // ... 其他代码不变 }
- 建议把API Key放到环境变量里,不要硬编码在代码中,避免泄露。
完成这些修改后,你应该就能正常获取到天气的JSON数据,而不是HTML代码了。
内容的提问来源于stack exchange,提问作者Karthik KK
相关产品推荐
相关产品推荐

