You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web调用Google Maps API时的CORS问题解决方法

Flutter Web Google Maps地点自动补全CORS问题排查

问题背景

在Flutter Web中实现Google Maps地点自动补全功能,调用API地址为:
https://maps.googleapis.com/maps/api/place/autocomplete/json?type=geocode&language=de&key=API_KEY&input=puratchi

功能在移动端运行正常,但Web端触发CORS错误。已在Google控制台移除所有API限制,同时配置了Nginx的CORS策略,但问题依旧。

现有实现代码

使用GetConnect的请求代码

Future<List<Prediction>> fetchingAutocomplete(String searchText) async {
  Uri autocompleteUri = Uri.parse(
      "https://maps.googleapis.com/maps/api/place/autocomplete/json?type=geocode&language=${kLanguageCode.value}&key=$kGoogleApiKey&input=$searchText");
  Response response = await GetConnect().get("$autocompleteUri",headers: {"Content-Type": "application/json"});
  if (response.statusCode == 200) {
    return AutocompleteModel.fromJson(response.body).predictions;
  } else {
    return AutocompleteModel.fromJson({}).predictions;
  }
}

使用Dio的请求代码

Future<List<Prediction>> fetchingAutocomplete(String searchText) async {
  final client = dio.Dio();
  // Add an interceptor to set headers before each request
  client.interceptors.add(dio.InterceptorsWrapper(
    onRequest: (dio.RequestOptions options, dio.RequestInterceptorHandler handler) {
      options.headers['Access-Control-Allow-Origin'] = 'https://angular.babelonia.nl';
      options.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS';
      options.headers['Access-Control-Allow-Headers'] = 'Content-Type';
      options.headers['Access-Control-Allow-Credentials'] = 'true';
      handler.next(options);
    },
  ));
  Uri autocompleteUri = Uri.parse(
      "https://maps.googleapis.com/maps/api/place/autocomplete/json?type=geocode&language=${kLanguageCode.value}&key=$kGoogleApiKey&input=$searchText");
  dio.Response response = await client.get("$autocompleteUri", options: dio.Options(headers: {"Content-Type": "application/json"}));
  if (response.statusCode == 200) {
    return AutocompleteModel.fromJson(response.data).predictions;
  } else {
    return AutocompleteModel.fromJson({}).predictions;
  }
}

Nginx CORS配置

location / {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
    add_header 'Access-Control-Allow-Headers' 'Content-Type';
    add_header 'Access-Control-Allow-Credentials' 'true';
}

报错信息

Access to XMLHttpRequest at 'https://maps.googleapis.com/maps/api/place/autocomplete/json?type=geocode&language=en&key=API_KEY&input=c' from origin 'https://angular.babelonia.nl' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

问题分析与解决方案

核心错误点

  1. 请求头设置错误:你在Dio拦截器中添加的Access-Control-*系列头是响应头,不属于请求头范畴。这些头应该由目标服务器(Google Maps API)返回,前端请求携带这些头不仅无效,还可能触发额外预检请求。
  2. Nginx配置未生效:当前请求是前端直接发送到maps.googleapis.com,完全绕开了你的Nginx服务器,所以Nginx的CORS配置对这个请求没有任何作用。

正确解决方案

方案1:使用Google Maps JavaScript SDK(推荐)

Google官方推荐Web环境下使用JavaScript SDK实现地点自动补全,该SDK通过加载脚本的方式调用,不受浏览器CORS限制,是最适配Web场景的方案。

方案2:搭建后端代理服务器

在你的Nginx服务器上配置反向代理,让前端请求先发送到自己的服务器,再由服务器转发到Google Maps API,这样Nginx的CORS配置就能生效:

  1. 修改Nginx配置,添加代理规则:
location /google-places-autocomplete {
    add_header 'Access-Control-Allow-Origin' 'https://angular.babelonia.nl';
    add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type';
    add_header 'Access-Control-Allow-Credentials' 'true';

    # 处理OPTIONS预检请求
    if ($request_method = OPTIONS) {
        return 204;
    }

    # 转发请求到Google Maps API
    proxy_pass https://maps.googleapis.com/maps/api/place/autocomplete/json;
    proxy_set_header Host maps.googleapis.com;
    proxy_set_header X-Real-IP $remote_addr;
}
  1. 修改Flutter Web中的请求地址,指向代理接口:
Uri autocompleteUri = Uri.parse(
    "https://your-domain.com/google-places-autocomplete?type=geocode&language=${kLanguageCode.value}&key=$kGoogleApiKey&input=$searchText");

方案3:检查Google API控制台配置

确认以下两点:

  • 已启用Places API(仅移除限制不够,需确保API本身已开启)
  • API密钥的应用限制中,可尝试添加https://angular.babelonia.nl作为允许的HTTP引用,避免潜在权限问题

额外优化建议

  • 移除Dio拦截器中所有Access-Control-*的请求头设置
  • GetConnect请求中,GET请求无需设置Content-Type: application/json,可移除该头以减少预检请求触发概率

内容的提问来源于stack exchange,提问作者Senthur Kumaran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:20:56