2017-04-01 140 views
1

我一直在努力通過這幾天 - 我已經得到它的工作方式,但我仍然遇到了我將在下面描述的路障。它已經到了我只需要從具有必要經驗的人那裏徵求一些建議的地步。Google Places API Web服務服務器端解決方案

原來這就是我最終想實現:

  1. 網頁負載和用戶看到他們的當地谷歌地圖
  2. 還有的地圖旁邊的品牌名單,如「特易購」和 「沃爾瑪」,例如
  3. 當用戶點擊沃爾瑪,他們會 看到所有沃爾瑪商店在地圖上的本地區域 - 地圖上被點擊 標記時,彈出將包含商店名稱,地址 等

真的非常簡單的功能。

我原來使用的是Google Maps JavaScript API以及Google Places API JavaScript Library

我得到了基本功能的工作,但跑進OVER_QUERY_LIMIT問題。

我發現這種情況是因爲正在作出(無關的日常使用限制),同時請求;例如當用戶點擊「沃爾瑪」時,試圖同時在地圖上顯示10多個商店被谷歌攔截。

從我的研究看來,我必須改用Google Maps API網絡服務

If too many requests are made within a certain time period, the API returns an OVER_QUERY_LIMIT response code. The per-session rate limit prevents the use of client-side services for batch requests. For batch requests, use the Maps API web services.

因此,我還是第二次使用Google Places API Web服務工作,這讓我很滿意。我使用AJAX請求從谷歌的JSON,但現在我得到以下控制檯錯誤:

XMLHttpRequest cannot load https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=53.000403,-1.129625&radius=10000&name=Sainsbury 's|Debenhams&key=AIzaSyBJPuiaP0Xptia5x3aKgizYLkzqMTAdMMg. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

我知道,因爲我從不同的服務器/域請求我得到這個錯誤。這裏是我的代碼,我只是此刻本地運行:

accessURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="+userCords.latitude+","+userCords.longitude+"&radius=10000&name=Sainsbury's|Debenhams&key=AIzaSyBJPuiaP0Xptia5x3aKgizYLkzqMTAdMMg"; \t 
 

 
$.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. \t 
 
      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 
 
    } 
 
});

爲了進行測試,我用這個前綴https://crossorigin.me到API的訪問網址,以解決此問題暫時得到,但現在我實際上需要正確地解決問題。

經過一番研究,我看到很多人建議將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 Uncaught SyntaxError: Unexpected token :

甚至更​​多的研究成最新的錯誤後,我看到喜歡的東西「看起來像的地方API不支持AJAX或JSONP」在我已經完成所有工作之後,這非常煩人!

然後我看到了這一點:

The Google Places API Web Service is for use in server applications. If you're building a client-side application, take a look at the Google Places API for Android and the Places Library in the Google Maps JavaScript API.

這意味着現在我已經走了一圈!

我在哪裏,我想我得把服務器端解決方案,而不是客戶端的一個點。但說實話,我不知道該從哪裏出發,在網上找不到任何東西指向正確的方向。

任何人都可以請告知下一步該怎麼做?什麼是「服務器端解決方案」?我走過這麼遠,我真的不想現在就放棄!任何幫助將巨大讚賞!

+0

你有沒有使用[JS API客戶端庫(https://developers.google.com/api-client-library/javascript/)谷歌提供認證和批量請求考慮? :) – Magix

回答

0

爲了解決你應該建立自己的中間服務器,將請求發送到谷歌(服務器端請求)的問題,並通過JSON響應返回給客戶端應用程序。換句話說,你應該建立一個代理來避免CORS問題。

你如何建立代理服務器,它是完全取決於你。選擇您熟悉的技術(Java,Python,NodeJs等)並實現服務器端代碼。

客戶端側的代碼將發送請求到中間服務器,中間服務器將發送HTTPS請求谷歌和通過響應返回給客戶端。

有GitHub上的一些有用的庫,你可以使用服務器端使用的NodeJS,使用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

希望能幫助到你!

+0

感謝您的回覆!我不知道從哪裏開始構建自己的代理服務器,您能否指出我可以幫助我的一些入門級指南/教程/文檔的方向? – user2586455

+0

以下是關於使用nodejs構建http web服務器的介紹性文章:https://blog.xervo.io/build-your-first-http-server-in-nodejs – xomena

+0

再次感謝,這對我來說是非常新的。當我將文件放在一臺實時服務器上時,會發生什麼情況?它們是否會同樣工作?構建一個http web服務器和nodejs並僅使用諸如MAMP之類的東西有什麼區別?服務器端對Google的請求是否不能用PHP編寫?再次,任何進一步的幫助將不勝感激。 – user2586455

0

我得到了相同的OVER_QUERY_LIMIT消息有關發送90名的請求,下面是一些解決方案,從StackOverflow的排序方式:

  1. 延遲請求
  2. 如果OVER_QUERY_LIMIT,重試此請求
  3. 變化從請求clientService到webService。 See more from google api document

,所以我儘量拖延我requets,但這並不能阻止OVER_QUERY_LIMIT,但會大大縮短frequency.Here大約是谷歌地圖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; 
 
}

相關問題