如何使用 CORS 实现 JavaScript Google Places API 请求

How to use CORS to implement JavaScript Google Places API request

提问人:Ryan Mc 提问时间:2/12/2017 更新时间:9/7/2022 访问量:53841

问:

我真的不明白我应该如何完成这项工作:

var requestURL = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw';

console.log(requestURL);

$.getJSON( requestURL, function( data ) {
  // data
  console.log(data);
});

和我的 HTML 文件:

  <body>

        <script
  src="https://code.jquery.com/jquery-2.2.4.min.js"
  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
  crossorigin="anonymous"></script>
        <script src="main.js" charset="utf-8"></script>   
  </body>

我总是得到请求的资源上不存在“Access-Control-Allow-Origin”标头。 消息...即使我在浏览器中转到 https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw,我也会返回正确的JSON。

我被引导相信CORS可以在这里帮助我。我不了解CORS。拜托,谁能用简单的术语帮助我?我应该更改什么才能使它工作??

谢谢

JavaScript JSON Google-API CORS

评论

0赞 Kevin Christopher Henry 2/12/2017
首先要做的是查看 Google 地方信息是否支持 CORS。如果没有,就没有意义了。我的猜测是他们只支持 JSONP,但请查看文档。
0赞 Ryan Mc 2/12/2017
确实如此,但我太笨了,无法理解它 developers.google.com/api-client-library/javascript/features/......
2赞 vhs 6/11/2017
我不确定为什么这被标记为重复。显然不是。
0赞 Jonas Wilms 4/23/2019
如果你来到这里,你可能应该阅读有关CORS的信息。要解决您在使用 google places API 时出现的具体错误,请阅读以下答案:

答:

47赞 rd3n 2/12/2017 #1

您正在尝试在客户端使用 Google Places API Web Service,而它是为服务器端应用程序设计的。这可能就是服务器未设置适当的 CORS 响应标头的原因。

地点详细信息文档开头的注释中所述,您应使用 Google Maps JavaScript API 中的地点库:

如果您要构建客户端应用,请查看 Google Maps JavaScript API 中的 Android 版 Google 地方 APIiOS 版 Google 地方 APIPlaces 库

注意:您需要先在 Google 开发者控制台中启用 Google Maps JavaScript API。

您可以通过以下方式继续获取地点详细信息(基于文档中的示例):

<head>
    <script type="text/javascript">
        function logPlaceDetails() {
          var service = new google.maps.places.PlacesService(document.getElementById('map'));
          service.getDetails({
            placeId: 'ChIJN1t_tDeuEmsRUsoyG83frY4'
          }, function (place, status) {
            console.log('Place details:', place);
          });
        }
    </script>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw&libraries=places&callback=logPlaceDetails"></script>
</head>
<body>
    <div id="map"></div>
</body>

Google Place details output to the console

评论

1赞 Ryan Mc 2/12/2017
这看起来不错,但有几件事:1)你正在使用ES6(我还不了解ES6),2)它对我不起作用,3)我不想要地图,我只想返回该地点的对象,这样我就可以输出数据。感谢您的帮助
0赞 rd3n 2/12/2017
1)我刚刚替换了,所以没有更多的ES6,2)你能详细说明一下吗?控制台中是否有错误?3)我不是谷歌地图专家,但似乎你可以提供一个Dom节点而不是一个地图实例,所以没有地图被渲染。我已经相应地测试并更新了代码constvar(place, status) =>function(place, status)PlacesService
0赞 Ryan Mc 2/12/2017
我终于通过修改 Google 文档上的示例来使其工作。谢谢,你的回答为我指明了正确的方向。
9赞 rmutalik 3/12/2019
@RyanMc既然 rd3n 的回答没有回答您的问题,您能否将修改后的代码作为答案发布?我很想看看你做了什么。
3赞 macabeus 12/9/2019 #2

@rd3n已经回答了为什么要使用 Google Maps 的 SDK,但如果你真的需要在 Web 应用程序上使用 API 而不是 SDK(例如重用代码),您可以使用 Webpack 的 DevServer 中的参数绕过 CORS。proxy

const GMAPS_PLACES_AUTOCOMPLETE_URL = (
  process.env.NODE_ENV === 'production'
    ? 'https://maps.googleapis.com/maps/api/place/autocomplete/json'
    : 'place-api' // on development, we'll use the Webpack's dev server to redirect the request

const urlParams = new URLSearchParams([
  ...
])

const response = await fetch(
  `${GMAPS_PLACES_AUTOCOMPLETE_URL}?${urlParams}`,
  { method: 'GET' }
)

而在你的...webpack.config.js

module.exports = {
  devServer: {
    proxy: {
      '/place-api': {
        target: 'https://maps.googleapis.com/maps/api/place/autocomplete/json',
        changeOrigin: true,
        pathRewrite: { '^/place-api': '' }
      }
    }
  }
}

评论

4赞 Sebastien Lorber 4/23/2020
但是,您如何在生产中使其工作 CORS 安全性也在这里
0赞 Mahan Mashoof 10/19/2021 #3

使用您提供的相同 url,这是针对纯前端 (React) 的,但解决方案不太安全:

var requestURL = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw';

从 url: 'https://maps.googleapis.com/maps/api/place' 中剪掉以下内容,并在您的package.json中创建一个代理行:

"proxy": "https://maps.googleapis.com/maps/api/place"

然后,按照谷歌文档,您将得到以下代码(无论您在哪里获取 api):

var axios = require('axios');

var config = {
  method: 'get',
  url: '/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw', //the rest of your url
  secure: false //important
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});
1赞 nourhomsi 9/7/2022 #4

我知道这是一个老问题,这可能不是这个问题的直接答案,但以防万一有人可以使用这个技巧,我总是喜欢使用 PHP 来解决这个问题,创建我自己的 API,然后使用 JavaScript 获取新创建的 API:

1# 创建一个 api.php 文件:

<?php
$google_URL = 'https://maps.googleapis.com/maps/api/place/details/json';
$api = 'YOUR_GOOGLE_API';
$place = 'PLACE_ID';    
$field = [
    'user_ratings_total',
    'rating'
];
    
$fields =  join(",", $field);
$result_url = $google_URL.'?placeid='.$place.'&fields='.$fields.'&key='.$api;
$result_content = file_get_contents($result_url);
$json_data = json_decode($result_content, true);

if ( isset($json_data) && $json_data['status'] === 'OK' ) {
    echo json_encode($json_data['result']);
}else {
    echo json_encode($json_data['error_message']);
}

header("content-type: application/json");

2# 创建脚本 .js 文件:

const url = './api.php';
fetch(url)
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.log(error))