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

Posted

技术标签:

【中文标题】如何使用 CORS 实现 JavaScript Google Places API 请求【英文标题】:How to use CORS to implement JavaScript Google Places API request 【发布时间】:2017-06-30 01:33:47 【问题描述】:

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

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>

我总是得到 No 'Access-Control-Allow-Origin' header is present on the requested resource. 消息...即使我在浏览器中转到 https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw 我得到返回正确的 JSON。

我相信 CORS 可以在这里帮助我。我不明白 CORS。拜托,谁能用简单明了的方式帮助我?我应该改变什么才能使这项工作?

谢谢

【问题讨论】:

首先要做的是看看 Google Places 是否支持 CORS。如果没有,那就没有意义了。我猜他们只支持 JSONP,但请查看文档。 确实如此,但我太笨了,无法理解它developers.google.com/api-client-library/javascript/features/… 我不知道为什么这被标记为重复。显然不是。 如果你来过这里,你可能应该阅读一下CORS。要使用 google places API 解决您的特定错误,请阅读以下答案: 【参考方案1】:

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

如Notes at the beginning of the Place Details documentation 中所述,您应该使用 Google Maps JavaScript API 中的 Places Library:

如果您正在构建客户端应用程序,请查看 Google Places API for android、Google Places API for ios 和 Places Library in the Google Maps JavaScript API。

注意:您需要先在 Google Developer Console 中启用 Google Maps JavaScript API。

您可以通过以下方式获取地点详细信息(基于example from the documentation):

<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>

【讨论】:

这看起来不错,但有几点:1)您使用的是 ES6(我还不了解 ES6),2)它不适合我,3)我不想要地图,我只是想要返回该地点的对象,以便我可以以我选择的任何方式输出数据。感谢您的帮助 1) 我刚刚将const 替换为var,将(place, status) =&gt; 替换为function(place, status),所以没有更多的ES6,2) 你能详细说明一下吗?您在控制台中有错误吗? 3) 我不是谷歌地图专家,但您似乎可以向PlacesService 提供一个 Dom 节点而不是地图实例,因此不会呈现地图。我已经相应地测试并更新了代码 我终于通过修改 Google 文档中的示例来实现这一点。谢谢,您的回答为我指明了正确的方向。 @RyanMc 因为 rd3n 的回答没有回答您的问题,您可以发布修改后的代码作为答案吗?我很想看看你做了什么。【参考方案2】:

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

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': '' 
      
    
  

【讨论】:

但是,如何在生产环境中进行这项工作,cors 安全性也在这里【参考方案3】:

使用您提供的相同网址,这是针对纯前端 (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"

然后按照 google 文档,您将得到以下代码(无论您在哪里获取 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);
);

【讨论】:

以上是关于如何使用 CORS 实现 JavaScript Google Places API 请求的主要内容,如果未能解决你的问题,请参考以下文章

如何使用“no-cors”将 JavaScript HTTP 发布请求代码更改为 C#?

如何使用javascript解决cors? [复制]

什么是跨域?如何实现跨域访问?

Slim 框架上 CORS 期间的预检授权标头

JavaScript实现jsonp&&CORS

如何在使用 javascript fetch 函数时设置公共 Google Cloud Storage 存储桶的 CORS 以避免错误?