可以通过AJAX使用Google Maps / Places的“自动填充”API吗?

时间:2011-07-23 21:48:06

标签: javascript jquery json google-api xmlhttprequest

我正在尝试使用Google地方信息自动填充API在网络应用程序上预先填写表单,其中包含企业数据以简化数据输入。 API非常简单,但它似乎不想接受XHR。

$.getJSON("https://maps.googleapis.com/maps/api/place/autocomplete/json",{
  input: input.term,
  sensor: false,
  types: 'establishment',
  location: '40.01496,-105.27029',
  radius: 10000,
  key: Config.googleplaceskey
},function(places_response){
    //Some other code.
});

我在控制台中得到了这个:

XMLHttpRequest cannot load https://maps.googleapis.com/maps/api/place/autocomplete/json?input=At&sensor=false&types=establishment&location=40.01496%2C-105.27029&radius=10000&key=AIzaSyDKzUgcLklQE_U5494vHq_SzrFakNHugaQ. Origin http://localhost:8086 is not allowed by Access-Control-Allow-Origin.

这在某种程度上不是API的意思吗?任何人都知道一个变通方法,或者我可以发送一些额外的参数来使它工作吗?

更新

以下是此次调用的API文档的链接。父文档实际上甚至还有JavaScript JSON解析示例。真的很混淆为什么会在服务器端关闭它。

http://code.google.com/apis/maps/documentation/places/autocomplete.html

7 个答案:

答案 0 :(得分:2)

要进行这样的跨域AJAX调用,您应该将JSONP与回调一起使用。但是,Google doesn't provide a JSONP interface for Autocomplete

您可能可以使用this Autocomplete class,但似乎无法设置下拉列表的样式。

编辑可能有办法做到这一点。查看geo-autocomplete jQuery Plugin。它有two demos。但是,我还没有正确地看一下。

答案 1 :(得分:2)

有两种方法可以访问Google Maps Autocomplete API。

第一个是通过google.maps.places.Autocomplete课程。这提供了Javascript中所有必要的实现。但是,您可以完全控制样式。使用pac-containerpac-item CSS类。

第二个是通过Autocomplete Web Service。由于same origin policy(没有JSONP API),无法通过浏览器访问此内容。这是访问自动填充结果的最灵活方式。

答案 2 :(得分:1)

Google可能只允许通过自己的Javascript API调用此API,您可以从maps.google.com提供的Javascript文件中加载该API。缺少Access-Control-Allow-Origin标头告诉您不应该通过Javascript使用API​​。

或者,您可以简单地编写一个服务器端代理函数,该函数调用Google API并将结果传递给您自己的$ .getJSON调用,但这可能违反了服务条款。

http://www.daniweb.com/web-development/php/code/216729

(免责声明:我还没有阅读此特定函数调用的API规范)

答案 3 :(得分:1)

您可以截取JSONP功能返回的google.maps.places.Autocomplete结果,并根据需要使用它们。

基本上,您在head元素上重新定义了appendChild方法,然后监视Google自动完成代码插入到JSONP的DOM中的javascript元素。添加javascript元素后,您将覆盖Google定义的JSONP回调,以便访问原始自动填充数据。

这是一个黑客,这里(我使用jQuery,但这不是必要的工作):

//The head element, where the Google Autocomplete code will insert a tag 
//for a javascript file.
var head = $('head')[0];  
//The name of the method the Autocomplete code uses to insert the tag.
var method = 'appendChild';  
//The method we will be overriding.
var originalMethod = head[method];

head[method] = function () {
  if (arguments[0] && arguments[0].src && arguments[0].src.match(/GetPredictions/)) {  //Check that the element is a javascript tag being inserted by Google.
    var callbackMatchObject = (/callback=([^&]+)&|$/).exec(arguments[0].src);  //Regex to extract the name of the callback method that the JSONP will call.
    var searchTermMatchObject = (/\?1s([^&]+)&/).exec(arguments[0].src);  //Regex to extract the search term that was entered by the user.
    var searchTerm = unescape(searchTermMatchObject[1]);
    if (callbackMatchObject && searchTermMatchObject) {
      var names = callbackMatchObject[1].split('.');  //The JSONP callback method is in the form "abc.def" and each time has a different random name.
      var originalCallback = names[0] && names[1] && window[names[0]] && window[names[0]][names[1]];  //Store the original callback method.
      if (originalCallback) {
        var newCallback = function () {  //Define your own JSONP callback
          if (arguments[0] && arguments[0][3]) {
            var data = arguments[0][4];  //Your autocomplete results
            //SUCCESS! - Limit results here and do something with them, such as displaying them in an autocomplete dropdown.
          }
        }

        //Add copy all the attributes of the old callback function to the new callback function. This prevents the autocomplete functionality from throwing an error.
        for (name in originalCallback) {  
          newCallback[name] = originalCallback[name];
        }
        window[names[0]][names[1]] = newCallback;  //Override the JSONP callback
      }
    }

  //Insert the element into the dom, regardless of whether it was being inserted by Google.
  return originalMethod.apply(this, arguments);
};

答案 4 :(得分:0)

这是一个跨域请求。浏览器默认阻止来自跨域网站的响应。你需要使用jsonp作为datatyoe。只需谷歌相同,你可以看到如何使用jquery API完成它。堆栈溢出也存在问题。

在相同的原始策略下,server1.example.com提供的网页通常无法连接到server1.example.com以外的服务器或与之通信。 HTML元素是一个例外。利用元素的开放策略,一些页面使用它们来检索对来自其他来源的动态生成的JSON格式数据进行操作的Javascript代码。此使用模式称为JSONP。

请注意,Google商家信息不符合JSONP标准,因此我使用的是Google Places JavaScript API。

答案 5 :(得分:0)

使用Google Maps Javascript API中的地方资料库: Javascript Places Autocomplete

Places API与Maps API不同。

答案 6 :(得分:-1)

您可以使用PHP绕过此问题。

在PHP脚本中,使用file_get_contents查询URL,如下所示:

$ suggestions = json_decode(file_get_contents('https://maps.googleapis.com/maps/api/place/autocomplete/json?input=blabla&sensor=false&types=establishment&radius=10000')

然后,您只需对PHP脚本使用AJAX请求,该请求将有效地绕过跨域约束返回结果。