Flutter Web调用Google Places API遇Dio XMLHttpRequest错误求助
问题:Flutter Web调用Google Places API出现XMLHttpRequest错误
我参考视频开发了附近地点搜索的Flutter代码,只把原代码里的data:parameters改成了queryParameters:parameters(原写法有红色下划线错误),但运行Flutter Web时出现错误:Error: DioError [DioErrorType.response]: XMLHttpRequest error。附上代码和完整报错栈,已经搜索过解决方案但没用,求帮忙解决。
代码实现
import 'package:flutter/material.dart'; import 'dart:async'; import 'package:dio/dio.dart'; void main() { runApp(MyApp()); } class MyApp extends StatefulWidget { @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { static const nycLat = 40.7484445; static const nycLng = -73.9878531; static const apiKey = "My_Api_Key"; @override Widget build(BuildContext context) { return Container(); } @override void didChangeDependencies() async { super.didChangeDependencies(); print(await searchNearby('hospital')); } Future<List<String>> searchNearby (String keyword) async { var dio = Dio(); var url = 'https://maps.googleapis.com/maps/api/place/nearbysearch/output?parameters'; var parameters = { 'key' : apiKey, 'location':'$nycLat,$nycLng', 'radius' : '800', 'keyword' : keyword, }; var response = await dio.get(url, queryParameters:parameters); return response.data['results'] .map<String>((result) => result['name'].toString()) .toList(); } }
完整报错栈
Running with sound null safety Debug service listening on ws://127.0.0.1:56039/Y3tKhTSoDB8=/ws Flutter Web Bootstrap: Auto Error: DioError [DioErrorType.response]: XMLHttpRequest error. Source stack: C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 963:28 get current packages/dio/src/dio_mixin.dart 488:35 fetch C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/dio/src/dio_mixin.dart 487:31 fetch packages/dio/src/dio_mixin.dart 483:12 request C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/dio/src/dio_mixin.dart 453:33 request packages/dio/src/dio_mixin.dart 61:12 get packages/leftover/main.dart 41:29 searchNearby C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/leftover/main.dart 32:37 searchNearby packages/leftover/main.dart 30:17 didChangeDependencies$ C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/leftover/main.dart 28:29 didChangeDependencies packages/flutter/src/widgets/framework.dart 4963:11 [_firstBuild] packages/flutter/src/widgets/framework.dart 4781:5 mount packages/flutter/src/widgets/framework.dart 3817:15 inflateWidget packages/flutter/src/widgets/framework.dart 3551:18 updateChild packages/flutter/src/widgets/binding.dart 1202:16 [_rebuild] packages/flutter/src/widgets/binding.dart 1171:5 mount packages/flutter/src/widgets/binding.dart 1119:16 <fn> packages/flutter/src/widgets/framework.dart 2597:19 buildScope packages/flutter/src/widgets/binding.dart 1118:12 attachToRenderTree packages/flutter/src/widgets/binding.dart 952:24 attachRootWidget packages/flutter/src/widgets/binding.dart 933:7 <fn> C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19 internalCallback at Object.throw_ [as throw] (http://localhost:55923/dart_sdk.js:5080:11) at http://localhost:55923/packages/dio/src/interceptors/log.dart.lib.js:1043:21 at _RootZone.runBinary (http://localhost:55923/dart_sdk.js:40515:59) at _FutureListener.catchError.handleError (http://localhost:55923/dart_sdk.js:35449:33) at handleError (http://localhost:55923/dart_sdk.js:36015:51) at _Future._propagateToListeners (http://localhost:55923/dart_sdk.js:36041:17) at [_completeError] (http://localhost:55923/dart_sdk.js:35878:23) at [_completeError] (http://localhost:55923/dart_sdk.js:35358:36) at _SyncCompleter.new.completeError (http://localhost:55923/dart_sdk.js:35282:29) at onError (http://localhost:55923/dart_sdk.js:35122:49) at _RootZone.runBinary (http://localhost:55923/dart_sdk.js:40515:59) at _FutureListener.then.handleError (http://localhost:55923/dart_sdk.js:35449:33) at handleError (http://localhost:55923/dart_sdk.js:36015:51) at _Future._propagateToListeners (http://localhost:55923/dart_sdk.js:36041:17) at [_completeError] (http://localhost:55923/dart_sdk.js:35878:23) at async._AsyncCallbackEntry.new.callback (http://localhost:55923/dart_sdk.js:35927:31) at Object._microtaskLoop (http://localhost:55923/dart_sdk.js:40778:13) at _startMicrotaskLoop (http://localhost:55923/dart_sdk.js:40784:13) at http://localhost:55923/dart_sdk.js:36261:9
解决方案
1. 修正API请求URL
当前URL格式错误,Google Places Nearby Search API需要指定输出格式(比如json),且不需要末尾的?parameters(Dio的queryParameters会自动拼接参数)。修正后:
var url = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json';
2. 解决Flutter Web跨域问题
浏览器的CORS限制会阻止直接调用Google Places API,有两种解决方式:
- 后端代理:在自己的后端服务中封装API请求,前端调用后端接口绕过跨域限制。
- 配置API Key来源白名单:在Google Cloud控制台中,为你的API Key添加允许的请求来源(比如开发环境的
http://localhost:55923),开发阶段可临时设为*(生产环境需严格限制)。
3. 修复生命周期方法异步问题
didChangeDependencies是同步方法,不能直接标记为async,需内部启动异步任务:
@override void didChangeDependencies() { super.didChangeDependencies(); _fetchNearbyPlaces(); } Future<void> _fetchNearbyPlaces() async { print(await searchNearby('hospital')); }
4. 添加空安全判断
response.data['results']可能为null,需增加空处理避免崩溃:
Future<List<String>> searchNearby(String keyword) async { var dio = Dio(); var url = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json'; var parameters = { 'key': apiKey, 'location': '$nycLat,$nycLng', 'radius': '800', 'keyword': keyword, }; var response = await dio.get(url, queryParameters: parameters); final results = response.data['results'] as List?; return results?.map<String>((result) => result['name'].toString()).toList() ?? []; }
内容的提问来源于stack exchange,提问作者Bella Lee
相关产品推荐
相关产品推荐

