谷歌地点 API - 请求的资源上没有“Access-Control-Allow-Origin”头。因此,来自“null”的源不被允许访问。

58

我正在使用Google Place API。

我想要获取有关某种类型场所的建议。

所以,我已经完成的工作是-

var Google_Places_API_KEY = "AIzaSyAK08OEC-B2kSyWfSdeCzdIkVnT44bcBwM";      //Get it from - https://code.google.com/apis/console/?noredirect#project:647731786600:access
var language = "en";        //'en' for English, 'nl' for Nederland's Language


var Auto_Complete_Link = "https://maps.googleapis.com/maps/api/place/autocomplete/json?key="+Google_Places_API_KEY+"&types=geocode&language="+language+"&input=Khu";
$.getJSON(Auto_Complete_Link , function(result)
{
    $.each(result, function(i, field)
    {
        //$("div").append(field + " ");
        //alert(i + "=="+ field);
        console.error(i + "=="+ field);
    });
});

我正在请求的链接是 -

https://maps.googleapis.com/maps/api/place/autocomplete/json?key=AIzaSyAK08OEC-B2kSyWfSdeCzdIkVnT44bcBwM&types=geocode&language=en&input=Khu

如果我用浏览器打开这个链接,我可以获得像这样的输出 (请尝试一下)-

11

但如果我使用jQuery的.getJSON.ajax尝试,则会收到以下消息而阻止我的请求-

222

因此XMLHTTPRequest被阻止了,原因是 -

所请求的资源上没有 'Access-Control-Allow-Origin' 头。因此不允许来自 'null' 的访问。

我在StackOverflow 上查找此问题的解决方案,并阅读了这里这里,但并没有完美解决我的问题。

请问有人可以给我指点吗?


我也检查了这个 - https://dev59.com/H2Ij5IYBdhLWcg3wpmoH?noredirect=1&lq=1 但是没有运气 :( - Abrar Jahin
这些答案已经过时了,重复问题似乎是最新的。 - Jonas Wilms
8个回答

21

在@sideshowbarker的回答中找到了解决方法:

尝试从REST API获取数据时,“请求资源上不存在'Access-Control-Allow-Origin'头”

然后使用了以下方法使其工作:

const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${longitude}&radius=500&key=[API KEY]"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url) // https://cors-anywhere.herokuapp.com/https://example.com
.then(response => response.json())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))

更多信息可以在上面链接的答案中找到。


缺少必需的请求头。 必须指定 origin 或 x-requested-with 中的一个。 - Abdennour TOUMI
您也可以简单地进行jQuery请求:jQuery.getJSON(proxyurl+googlemapsurl,function(data){}); 感谢解决方案。 - Timur Gafforov
1
现在不起作用。 - Kunal Raut
1
不再起作用了。 - Becca

10

AJAX请求仅在发送方和接收方的端口、协议和域名相同时才可能发生,否则可能会导致CORS。CORS代表跨源资源共享,必须在服务器端支持。

解决方案

JSONP

JSONP或“带填充的JSON”是一种通信技术,用于JavaScript程序在Web浏览器中运行以从不同域中的服务器请求数据,这是由于同源策略而被常规Web浏览器禁止的。类似这样的东西可能会有所帮助.. :)

$.ajax({
            url: Auto_Complete_Link, 
            type: "GET",   
            dataType: 'jsonp',
            cache: false,
            success: function(response){                          
                alert(response);                   
            }           
        });    

非常感谢您,您节省了我的时间。 - Nimit Joshi
36
也对我不起作用,问题似乎是谷歌给你JSON,但你尝试dataType:jsonp,这会给我带来错误。 - m0j1
5
当我运行 JSONP 时,出现错误。以这种方式返回的 JSON 格式不正确。 - Joel
3
无效!迄今为止我所知道的是Google的API仅适用于JSON和XHTML格式。 - sphoenix
3
不再起作用了。目前没有错误,但警报方法没有打印任何内容。 - piepi
5
无法工作。 - Bo Pennings

8

谷歌提供API客户端库:

<script src="https://apis.google.com/js/api.js" type="text/javascript"></script>

它可以为您执行谷歌API请求,只需提供API路径和参数:
var restRequest = gapi.client.request({
  'path': 'https://people.googleapis.com/v1/people/me/connections',
  'params': {'sortOrder': 'LAST_NAME_ASCENDING'}
});

由于图书馆是从谷歌域名提供服务的,因此它可以安全地调用谷歌API而不会出现CORS问题。

关于如何使用CORS的谷歌文档。


2
由于某些原因,使用请求到 https://maps.googleapis.com/maps/api/place/details/json 时无法正常工作。我收到了一个404错误。 - alev

4

好的,以下是我们在JavaScript中的做法...谷歌有自己的函数来实现这个...

链接: https://developers.google.com/maps/documentation/javascript/places#place_search_requests

var map;
var service;
var infowindow;

function initialize() {
  var pyrmont = new google.maps.LatLng(-33.8665433,151.1956316);

  map = new google.maps.Map(document.getElementById('map'), {
      center: pyrmont,
      zoom: 15
    });

  var request = {
    location: pyrmont,
    radius: '500',
    types: ['store']
  };

  service = new google.maps.places.PlacesService(map);
  service.nearbySearch(request, callback);
}

function callback(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      var place = results[i];
      createMarker(results[i]);
    }
  }
}

如果有人想要获取地点Id和相关信息,可以按照以下方法进行操作... 在回调函数中,我们可以通过Google返回的地点JSONArray获得相应的信息... 在for循环内的回调函数中,在var place = results[i];这行代码后,你可以获取你想要的内容。

console.log(place.name);
console.log(place.place_id);
var types = String(place.types);
types=types.split(",");
console.log(types[0]);

3
我能够通过在与我的JavaScript文件在同一台服务器上创建一个PHP文件来解决问题。然后使用cURL从Google获取数据并将其发送回我的js文件。
PHP文件
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://maps.googleapis.com/maps/api/place/textsearch/xml?query=" . $_POST['search'] . "&key=".$api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;

JavaScript 文件
var search = encodeURI($("#input_field").val());
$.post("curl.php", { search: search }, function(xml){
  $(xml).find('result').each(function(){
    var title = $(this).find('name').text();
    console.log(title);
  });
});

使用此解决方案,我不会遇到任何CORS错误。


3

客户端没有使用ajax调用Google Place API的方法,也不能使用jsonp(语法错误:))或遇到跨域问题,

客户端唯一的方法是使用Google Javascript库, https://developers.google.com/maps/documentation/javascript/tutorial

或者您可以在服务器端获取Google Place API,然后为您的客户端创建自己的API。


1

你好,

请尝试使用Google距离矩阵。

    var origin = new google.maps.LatLng(detectedLatitude,detectedLongitude);       
    var destination = new google.maps.LatLng(latitudeVal,langtitudeVal);
    var service = new google.maps.DistanceMatrixService();
    service.getDistanceMatrix(
      {
        origins: [origin],
        destinations: [destination],
        travelMode: 'DRIVING',            
        unitSystem: google.maps.UnitSystem.METRIC,
        durationInTraffic: true,
        avoidHighways: false,
        avoidTolls: false
      }, response_data);

      function response_data(responseDis, status) {
      if (status !== google.maps.DistanceMatrixStatus.OK || status != "OK"){
        console.log('Error:', status);
        // OR
        alert(status);
      }else{
           alert(responseDis.rows[0].elements[0].distance.text);
      }
  });

如果您正在使用JSONP,有时会在控制台中出现缺少语句错误。 请参考此文档 点击这里

有时候谷歌API不允许在没有出发时间的情况下查找距离。您将收到错误消息,如“departure_time is in the past. Traffic information is only available for future and current times”。请添加“drivingOptions”。 - Nadimuthu Sarangapani

1
我这样访问Google Maps API:

    $scope.getLocationFromAddress = function(address) {
    if($scope.address!="Your Location"){
        $scope.position = "";
        delete $http.defaults.headers.common['X-Requested-With'];
        $http(
                {
                    method : 'GET',
                    url : 'https://maps.googleapis.com/maps/api/geocode/json?address='+ address+'&key=AIzaSyAAqEuv_SHtc0ByecPXSQiKH5f2p2t5oP4',

                }).success(function(data, status, headers, config) {

            $scope.position = data.results[0].geometry.location.lat+","+data.results[0].geometry.location.lng;                              
        }).error(function(data, status, headers, config) {
            debugger;
            console.log(data);
        });
    }
}

7
那是地理编码API,它与JS很好地配合。但地点/自动完成API则不行。 - ThadeuLuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接