Google Places API网络服务服务器端解决方案

时间:2017-04-01 21:04:53

标签: javascript json ajax google-maps-api-3 google-places-api

我几天来一直在努力解决这个问题 - 我已经按照我想要的方式努力了,但后来我一直遇到障碍,我将在下面介绍。它已经到了我需要向具有必要经验的人寻求建议的地步。

所以这就是我最终想要实现的目标:

  1. 网页加载,用户在Google地图上查看其本地区域
  2. 地图旁边有一个品牌列表,例如" Tesco"和 "沃尔玛"例如
  3. 当用户点击沃尔玛时,他们会 在地图上查看当地所有沃尔玛商店 - 当地图 单击标记,弹出窗口将包含商店名称,地址 等
  4. 在功能方面非常简单。

    我最初使用 Google Maps JavaScript API 以及 Google Places API JavaScript库

    我的基本功能正常运行,但遇到了OVER_QUERY_LIMIT问题。

    我发现这是因为同时发出请求(与日常使用限制无关);例如,当用户点击" Walmart"时,Google会阻止同时在地图上显示~10 +商店。

    根据我的研究,我似乎不得不使用 Google Maps API网络服务

      

    如果在特定时间段内发出的请求太多,则API会返回OVER_QUERY_LIMIT响应代码。每会话速率限制可防止对批处理请求使用客户端服务。 对于批量请求,请使用Maps API网络服务

    所以我也使用Google Places API Web服务第二次工作,我非常高兴。我使用AJAX从Google请求JSON,但现在我收到以下控制台错误:

      

    XMLHttpRequest无法加载https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=53.000403,-1.129625&radius=10000&name=Sainsbury' s | Debenhams& key = AIzaSyBJPuiaP0Xptia5x3aKgizYLkzqMTAdMMg。对预检请求的响应没有通过访问控制检查:否'访问控制 - 允许 - 来源'标头出现在请求的资源上。起源' null'因此不允许访问。

    我知道我收到此错误是因为我从其他服务器/域请求。这是我的代码,我现在正在本地运行:

    
    
    accessURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="+userCords.latitude+","+userCords.longitude+"&radius=10000&name=Sainsbury's|Debenhams&key=AIzaSyBJPuiaP0Xptia5x3aKgizYLkzqMTAdMMg";	
    
    $.ajax({
      type: "GET",
      contentType: "application/json; charset=utf-8",
      url: accessURL,
      dataType: 'json',
      success: function (data) {
    
        $.each(data.results, function (i, val) {
          storeId.push(val.place_id);
          storeName.push(val.name);
        });
    
        //Now, use the id to get detailed info
        $.each(storeId, function (k, v){
          $.ajax({
            type: "GET",
            contentType: "application/json; charset=utf-8",
            url: "https://maps.googleapis.com/maps/api/place/details/json?placeid="+v+"&key=AIzaSyBJPuiaP0Xptia5x3aKgizYLkzqMTAdMMg",
            dataType: 'json',
            success: function (data) {
    
              var latitude = data.result.geometry.location.lat;
              var longitude = data.result.geometry.location.lng;
    
              //set the markers.	  
              myLatlng = new google.maps.LatLng(latitude,longitude);
    
              allMarkers = new google.maps.Marker({
                position: myLatlng,
                map: map,
                title: data.result.name,
                html: '<div class="marker-content">' +
                    '<p>'+data.result.name+'</p>' +
                      '<p>'+data.result.formatted_address+'</p>' +
                    '</div>'
              });
    
              //put all lat long in array
              allLatlng.push(myLatlng);
    
              //Put the markers in an array
              tempMarkerHolder.push(allMarkers);
    
              google.maps.event.addListener(allMarkers, 'click', function () {
                infowindow.setContent(this.html);
                infowindow.open(map, this);
              });
    
              //  Make an array of the LatLng's of the markers you want to show
              //  Create a new viewpoint bound
              var bounds = new google.maps.LatLngBounds ();
              //  Go through each...
              for (var i = 0, LtLgLen = allLatlng.length; i < LtLgLen; i++) {
                //  And increase the bounds to take this point
                bounds.extend (allLatlng[i]);
              }
              //  Fit these bounds to the map
              map.fitBounds (bounds);
    
    
            }
          });
        }); //end .each
      }
    });
    &#13;
    &#13;
    &#13;

    为了进行测试,我已经在API访问网址上使用了此https://crossorigin.me来暂时解决此问题,但现在我确实需要正确解决问题。

    经过一些研究,我看到很多人建议将dataType更改为jsonp。但是当我这样做时,我得到以下控制台错误:

      

    https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=53.041981899999996,-1.1898794&radius=10000&name=Sainsbury%27s|Debenhams&key=AIzaSyBJPuiaP0Xptia5x3aKgizYLkzqMTAdMMg&callback=jQuery111309486707670378429_1491079656734&_=1491079656735:2   未捕获的SyntaxError:意外的令牌:

    在对这个最新错误进行更多研究之后,我发现像#api这样的地方似乎不支持ajax或jsonp&#34;这在我拿到它之后非常烦人一切都在工作!

    然后我看到了这个:

      

    Google Places API Web服务用于服务器应用程序。如果您要构建客户端应用程序,请查看适用于Android的Google Places API和Google Maps JavaScript API中的商家库。

    这意味着我现在已经完整了!

    我想我必须制定服务器端解决方案,而不是客户端解决方案。但说实话,我不知道从哪里开始,无法在网上找到任何指示我正确方向的东西。

    任何人都可以建议下一步做什么?什么是服务器端解决方案&#34;看起来像?我走到这一步,我真的不想现在退出!任何帮助都将非常赞赏!

2 个答案:

答案 0 :(得分:0)

要解决此问题,您应该构建自己的中间服务器,将向Google发送请求(服务器端请求)并将JSON响应传递回客户端应用程序。换句话说,您应该构建一个代理来避免CORS问题。

如何构建代理服务器,完全取决于您。选择您熟悉的技术(Java,Python,NodeJs等)并实现服务器端代码。

客户端代码将向中间服务器发送请求,中间服务器将向Google发送HTTPS请求并将响应传递回客户端。

GitHub上有几个有用的库,您可以将服务器端与NodeJ,Java,Python或Go一起使用:

https://github.com/googlemaps/google-maps-services-js

https://github.com/googlemaps/google-maps-services-java

https://github.com/googlemaps/google-maps-services-python

https://github.com/googlemaps/google-maps-services-go

希望它有所帮助!

答案 1 :(得分:0)

我收到了关于发送90个请求的相同OVER_QUERY_LIMIT消息,以下是从stackOverFlow中解决的一些解决方案:

  1. 延迟请求
  2. 如果OVER_QUERY_LIMIT,请重试此请求
  3. 将请求从clientService更改为webService。See more from google api document
  4. 所以我试图延迟我的requets,这不能阻止OVER_QUERY_LIMIT,但会大大降低频率。这是我的谷歌地图api方向的核心功能,就像你的谷歌地图Api一样。

    function calculateDirections( directionsService, requestList, responseList, deferred, recursiveCount ) {
                var deferred = deferred || $q.defer();
                var responseList = responseList || [];
                var recursiveCount = recursiveCount || 0;
                var directionRequest = {
                    origin: requestList[ recursiveCount ].origin,
                    destination: requestList[ recursiveCount ].destination,
                    waypoints: requestList[ recursiveCount ].waypoints,
                    optimizeWaypoints: false,
                    travelMode: google.maps.TravelMode.DRIVING
                };
    
                directionsService.route( directionRequest, function ( response, status ) {
                    if ( status === google.maps.DirectionsStatus.OK ) {
                        responseList.push( response );
                        if ( requests.length > 0 ) {
                            //delay google request,millisecond
                            setTimeout( function () {
                                recursiveCount++;
                                calculateDirections( directionsService, requests, responseList, deferred, recursiveCount );
                            }, recursiveCount * 10 + 500 );
    
                        } else {
                            deferred.resolve( responseList );
                        }
                    }else if( status === google.maps.DirectionsStatus.OVER_QUERY_LIMIT ){
                        //try again google request
                        setTimeout( function () {
                            calculateDirections( directionsService, requests, responseList, deferred, recursiveCount );
                        }, recursiveCount * 10 + 500 );
                    } else {
                        var result = {};
                        result.status = status;
                        deferred.reject( result );
                    }
    
                } );
    
                return deferred.promise;
    }