Flutter中调用DistanceMatrix API的http.get请求异常求助
问题排查与解决方案
你遇到的核心矛盾是浏览器能正常请求但Dart代码调用失败,这通常和请求编码、请求头或API密钥限制有关,以下是具体排查步骤和修复方案:
1. 先获取具体错误信息
你的代码在请求失败时直接抛出通用异常,无法得知Google API返回的具体错误(比如参数格式错误、配额超限、请求被拦截等)。先修改代码打印错误响应内容:
} else { // 打印错误详情,这是排查的关键 print('Distance Matrix API 错误响应: ${response.body}'); throw Exception('Laden der Addresse fehlgeschlagen. Mehrere Addressen sind falsch.'); }
运行后查看控制台输出,就能明确API返回的错误码和原因,比如INVALID_REQUEST、OVER_QUERY_LIMIT等。
2. 修复URI编码问题
你手动拼接坐标字符串时用%2C代替逗号,但Dart的Uri.parse会自动处理编码,手动编码可能导致重复编码或格式错误。建议:
- 用普通逗号拼接经纬度,再用
Uri.https自动处理参数编码 - 用
map+join简化坐标字符串构建,避免循环拼接的失误
修改后的核心代码:
Future<List<List<int>>> fetchDistanceMatrix(List<PointLatLng> coords) async { // 简化坐标字符串构建,用逗号分隔经纬度,|分隔多个坐标 String fullAddressString = coords .map((coord) => '${coord.latitude},${coord.longitude}') .join('|'); // 用Uri.https自动处理参数编码,避免手动拼接的错误 final uri = Uri.https( 'maps.googleapis.com', '/maps/api/distancematrix/json', { 'destinations': fullAddressString, 'origins': fullAddressString, 'key': key, }, ); // 添加模拟浏览器的User-Agent头,避免被API拦截 final response = await http.get(uri, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', }); if (response.statusCode == 200) { dynamic jsonLocation = jsonDecode(response.body); List<List<int>> distanceMatrix = []; for (var i = 0; i < coords.length; i++) { List<int> rowVector = []; for (var j = 0; j < coords.length; j++) { String elementStatus = jsonLocation['rows'][i]['elements'][j]['status']; if (elementStatus == 'OK') { rowVector.add(jsonLocation['rows'][i]['elements'][j]['duration']['value']); } else { throw Exception('Laden der Addressen fehlgeschlagen: DistanceMatrixAPI kann die Koordinaten nicht finden. Status: $elementStatus'); } } distanceMatrix.add(rowVector); } return distanceMatrix; } else { print('Distance Matrix API 错误响应: ${response.body}'); throw Exception('Laden der Addresse fehlgeschlagen. Mehrere Addressen sind falsch.'); } }
3. 检查API密钥的限制设置
虽然浏览器能请求,但Google Cloud控制台的API密钥可能设置了HTTP referrer限制(仅允许特定网站域名访问),而Dart的请求没有referrer头,会被拦截。解决方法:
- 登录Google Cloud控制台,找到你的API密钥
- 把密钥的限制方式改成无限制(测试用),或者添加对应的请求来源(比如移动端应用的包名/签名)
4. 验证坐标格式
确保PointLatLng的latitude和longitude是合法数值(纬度在-90到90之间,经度在-180到180之间),若坐标格式错误,API会返回INVALID_REQUEST。
内容的提问来源于stack exchange,提问作者R. Alexander
相关产品推荐
相关产品推荐

