Flutter调用OpenWeatherMap接口报400错误,换密钥改代码仍无法解决
问题根源
你代码的核心问题是异步方法调用顺序错误,定位和网络请求没有按顺序执行:
getLocation()是异步耗时方法,你在initState中调用它之后没有等待它执行完成就直接调用了getData(),此时latitude和lontitude两个变量还未被赋值,默认是null,拼接成请求URL后参数非法,OpenWeatherMap校验不通过就返回400错误。- 额外注意你拼写的变量名
lontitude是拼写错误,正确拼写是longitude,如果你的Location类里的属性是正确拼写的话,也会导致拿到的经度永远是null。
解决方案
- 先修正变量拼写错误,把所有
lontitude改成正确的longitude,和你的Location类属性保持一致 - 调整异步调用逻辑,等待定位完成之后再发起网络请求,不要在
initState里直接先后调用两个异步方法。
修正后代码参考
import 'package:clima/services/location.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; const apiKey = '*****53a8**************'; class LoadingScreen extends StatefulWidget { @override _LoadingScreenState createState() => _LoadingScreenState(); } class _LoadingScreenState extends State<LoadingScreen> { // 修正拼写错误 double longitude; double latitude; @override void initState() { super.initState(); // 封装定位+请求逻辑到同一个方法里调用 getLocationThenGetData(); } // 合并逻辑,保证定位完成后再发起请求 Future getLocationThenGetData() async { Location location = Location(); await location.getCurrentLocation(); latitude = location.latitude; // 对应修正变量名 longitude = location.longitude; // 定位完成后再调用请求方法 await getData(); } Future getData() async { http.Response response = await http.get( Uri.parse( 'https://api.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude&appid=$apiKey'), ); if (response.statusCode == 200) { String data = response.body; var temperature = jsonDecode(data)['main']['temp']; print(temperature); var condition = jsonDecode(data)['weather'][0]['id']; print(condition); var city = jsonDecode(data)['name']; print(city); } else { print(response.statusCode); // 排查问题时可以加这行打印返回的错误详情,更容易定位问题 print(response.body); } } @override Widget build(BuildContext context) { return Scaffold(); } }
其他可能的排查点
如果修改后还是有400错误,可以按以下顺序检查:
- 确认你的API密钥已经生效,新申请的OpenWeatherMap密钥需要等待最多2小时才会激活
- 确认你传入的经纬度数值是合法的:纬度范围-9090,经度范围-180180
- 确认API请求地址和参数名称和官方文档一致,没有拼写错误
内容的提问来源于stack exchange,提问作者Mazen Bahy
相关产品推荐
相关产品推荐

