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

Flutter Web集成flutter_google_places遇空值及跨域错误求解决方案

解决Flutter Web中flutter_google_places的CORS及空值错误问题

你的问题核心是Flutter Web环境下直接调用Google Places API触发了浏览器的同源策略(CORS)限制,导致XMLHttpRequest错误;而空值错误通常是CORS请求失败后返回null引发的连锁问题。下面是几个长期可行的解决方案:

方案1:改用Google Places JavaScript API(推荐)

Flutter Web对原生JS API的支持更友好,官方的Places JS API不会有CORS问题,步骤如下:

  1. 在web/index.html的<head>中引入Google Places JS脚本(替换成你的API密钥):
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_API_KEY&libraries=places"></script>
    
  2. 在Dart代码中通过dart:js调用JS的自动完成功能:
    import 'dart:js' as js;
    import 'dart:html' as html;
    
    void initPlaceAutocomplete() {
      // 获取页面中的输入框元素
      final input = html.document.getElementById('place-input');
      // 调用Google Places Autocomplete
      final autocomplete = js.JsObject(js.context['google']['maps']['places']['Autocomplete'], [input]);
      // 监听地点选择事件
      js.context['handlePlaceSelect'] = (js.JsObject place) {
        final placeName = place['formatted_address'];
        final lat = place['geometry']['location']['lat']();
        final lng = place['geometry']['location']['lng']();
        // 处理选中的地点数据
        print('选中地点:$placeName,坐标:$lat,$lng');
      };
      autocomplete.callMethod('addListener', ['place_changed', () {
        final selectedPlace = autocomplete.callMethod('getPlace');
        js.context['handlePlaceSelect'](selectedPlace);
      }]);
    }
    
  3. 在页面中添加对应的输入框:
    <input type="text" id="place-input" placeholder="搜索地点">
    

方案2:搭建自己的CORS代理服务器

如果不想替换包,可以自己部署一个CORS代理来转发请求,彻底摆脱公共代理的限制:

用Node.js部署cors-anywhere

  • 克隆仓库并启动服务:
    git clone https://github.com/Rob--W/cors-anywhere.git
    cd cors-anywhere
    npm install
    # 启动服务器,默认端口8080
    node server.js
    
  • 部署到云平台(如Heroku、Vercel)后,将proxyBaseUrl改为你的代理地址:
    proxyBaseUrl: kIsWeb ? 'https://your-proxy-domain.com/https://maps.googleapis.com/maps/api' : null,
    

用Nginx做反向代理

在Nginx配置文件中添加反向代理规则,直接转发Places API请求:

location /google-places {
  proxy_pass https://maps.googleapis.com/maps/api;
  proxy_set_header Host maps.googleapis.com;
  add_header Access-Control-Allow-Origin *;
  add_header Access-Control-Allow-Methods GET, POST, OPTIONS;
  add_header Access-Control-Allow-Headers Content-Type;
}

之后将proxyBaseUrl设为https://your-nginx-domain.com/google-places

方案3:用Google Cloud Functions做中间层

搭建轻量级的云函数作为请求转发层,避免CORS问题:

  1. 创建一个Cloud Function,代码示例(Node.js):
    const axios = require('axios');
    
    exports.proxyPlaces = async (req, res) => {
      // 转发请求到Google Places API
      const apiUrl = `https://maps.googleapis.com/maps/api${req.url}`;
      try {
        const response = await axios.get(apiUrl);
        // 设置CORS头部
        res.set('Access-Control-Allow-Origin', '*');
        res.status(response.status).send(response.data);
      } catch (err) {
        res.set('Access-Control-Allow-Origin', '*');
        res.status(err.response?.status || 500).send(err.response?.data || '请求失败');
      }
    };
    
  2. 部署云函数后,将proxyBaseUrl设置为云函数的访问地址,比如https://your-cloud-function-url.cloudfunctions.net/proxyPlaces

以上方案都能彻底解决CORS限制问题,同时消除因请求失败导致的空值错误。

内容的提问来源于stack exchange,提问作者Chirag Mevada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:10:40