可以通过AJAX使用Google Maps / Places的“自动填充”API吗?
我正在尝试使用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
以下是遇到此方案的未来读者的代码段。
使用“Places API”而不是“Maps API”,此代码段会使用Google返回的数据填写我的表单元素(包括用于自动填充的输入)。
/* Use google place API to auto complete the address field and populate form inputs */ function addressAutoComplete(){ var planAddress = document.getElementById('mps_planaddress'), planCity = document.getElementById('mps_plancity'), planCounty = document.getElementById('mps_plancounty'), planZip = document.getElementById('mps_planzip'), planSub = document.getElementById('mps_plansubdivision'), options = { componentRestrictions: {country: 'us'} }; autocomplete = new google.maps.places.Autocomplete(planAddress, options); // After the user selects the address google.maps.event.addListener(autocomplete, 'place_changed', function() { planSub.focus(); var place = autocomplete.getPlace(); planAddress.value = place.name; planCity.value = place.address_components[2].long_name; planCounty.value = place.address_components[3].long_name; planZip.value = place.address_components[6].long_name; }); }
将一个监听器放在“place_changed”的自动完成中(他们从列表中选择了一些东西),然后用返回的数据填写输入。
所有这些都列在Place Library Google页面上 。
要像这样进行跨域AJAX调用,您应该将JSONP与回调一起使用。 但是, Google不为自动填充提供JSONP界面 。
您可能可以使用此自动完成类 ,但似乎无法设置下拉列表的样式。
编辑可能有办法做到这一点。 查看geo-autocomplete jQuery插件 。 它有两个 演示 。 然而,我还没有给出适当的看法。
有两种方法可以访问Google Maps Autocomplete API。
第一个是通过google.maps.places.Autocomplete
类。 这提供了Javascript中所有必要的实现。 但是,您可以完全控制样式。 使用pac-container
和pac-item
CSS类。
第二种是通过自动完成Web服务 。 由于原始策略相同 (没有JSONP API),因此无法通过浏览器访问。 这是访问自动填充结果的最灵活方式。
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规范)
您可以拦截google.maps.places.Autocompletefunction返回的JSONP结果,并根据需要使用它们。
基本上,您在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); };
这是一个跨域请求。 浏览器默认阻止来自跨域网站的响应。 你需要使用jsonp作为datatyoe。 只需谷歌相同,你可以看到如何使用jquery API完成它。 堆栈溢出也存在问题。
在相同的原始策略下,server1.example.com提供的网页通常无法连接到server1.example.com以外的服务器或与之通信。 HTML元素是一个例外。 利用元素的开放策略,一些页面使用它们来检索对来自其他来源的动态生成的JSON格式数据进行操作的Javascript代码。 此使用模式称为JSONP。
请注意,Google地方信息不符合JSONP标准,因此我使用的是Google Places JavaScript API。
使用Google Maps Javascript API中的地方资料库: Javascript地方自动填充function
Places API与Maps API不同。
您可以使用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请求,该请求将有效地绕过跨域约束返回结果。