Javascript 可以通过 AJAX 使用 Google Maps/Places 'autocomplete' API 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6803521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can Google Maps/Places 'autocomplete' API be used via AJAX?
提问by woodardj
I'm trying to use the Google Places autocomplete API to pre-fill a form on a web application with Establishment data to ease data-entry. The API is pretty straightforward, but it doesn't seem to want to accept the XHR.
我正在尝试使用 Google Places 自动完成 API 预先填写具有建立数据的 Web 应用程序上的表单,以简化数据输入。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.
});
I get this in the console:
我在控制台中得到这个:
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.
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.
Is this somehow not what the API is meant for? Anyone know a workaround, or some kind of extra parameter(s) I could send to make it work?
这在某种程度上不是 API 的用途吗?任何人都知道一种解决方法,或者我可以发送某种额外参数以使其工作?
Update:
更新:
Here's the link to the API documentation for this call. The parent docs actually even have JavaScript JSON-parsing examples. Really confusing why this would be shut down on the server side.
这是此调用的 API 文档的链接。父文档实际上甚至有 JavaScript JSON 解析示例。真的很困惑为什么这会在服务器端关闭。
http://code.google.com/apis/maps/documentation/places/autocomplete.html
http://code.google.com/apis/maps/documentation/places/autocomplete.html
回答by Lost in the sauce
Here is a code snippet for future readers who come across this scenario.
这是为遇到这种情况的未来读者提供的代码片段。
Using the "Places API" rather than the "Maps API", this code snippet fills in my form elements (including the input that is used to autocomplete) with returned data from Google.
使用“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;
});
}
Put a listener on the autocomplete for "place_changed" (they chose something from the list) and then fill in the inputs with the data returned.
在“place_changed”的自动完成上放置一个监听器(他们从列表中选择了一些东西),然后用返回的数据填充输入。
All of this is listed on the Place Library Google page.
所有这些都列在地方图书馆 Google 页面上。
回答by Chris Broadfoot
There are two ways to access the Google Maps Autocomplete API.
有两种方法可以访问 Google Maps Autocomplete API。
The first is via the google.maps.places.Autocomplete
class. This provides all the necessary implementation in Javascript. However, you have complete control over styling. Use the pac-container
and pac-item
CSS classes.
第一个是通过google.maps.places.Autocomplete
类。这在 Javascript 中提供了所有必要的实现。但是,您可以完全控制样式。使用pac-container
和pac-item
CSS 类。
The second is via the Autocomplete Web Service. This is not accessible via the browser because of same origin policy(there is no JSONP API). This is the most flexible way to access Autocomplete results.
第二种是通过自动完成 Web 服务。由于同源策略(没有 JSONP API),这无法通过浏览器访问。这是访问自动完成结果的最灵活的方式。
回答by Drew Noakes
To make cross-domain AJAX calls like this, you should use JSONP with a callback. However, Google doesn't provide a JSONP interface for Autocomplete.
要进行这样的跨域 AJAX 调用,您应该使用带有回调的 JSONP。但是,Google 没有为 Autocomplete 提供 JSONP 接口。
You might be able to use this Autocomplete classinstead, though it doesn't seem possible to style the dropdown.
您或许可以改用此 Autocomplete 类,但似乎无法设置下拉菜单的样式。
EDITThere may be a way to do this. Check out the geo-autocomplete jQuery Plugin. It has twodemos. I haven't given this a proper look over yet however.
编辑可能有办法做到这一点。查看geo-autocomplete jQuery Plugin。它有两个演示。然而,我还没有对此进行适当的审视。
回答by Mikko Ohtamaa
The Google probably allows this API only called through its own Javascript API which you load from maps.google.com served Javascript file. The lack of Access-Control-Allow-Origin header tells that you should not use the API otherwise through Javascript.
谷歌可能只允许通过它自己的 Javascript API 调用这个 API,你从 maps.google.com 提供的 Javascript 文件加载。缺少 Access-Control-Allow-Origin 标头告诉您不应通过 Javascript 以其他方式使用 API。
Alternatively you can simply write a server-side proxy function which calls Google API and passes the result forward to your own $.getJSON call, but this would be probably against the Terms of Service.
或者,您可以简单地编写一个服务器端代理函数,该函数调用 Google API 并将结果传递给您自己的 $.getJSON 调用,但这可能违反服务条款。
http://www.daniweb.com/web-development/php/code/216729
http://www.daniweb.com/web-development/php/code/216729
(disclaimer: I have not read the API spec for this particular function call)
(免责声明:我尚未阅读此特定函数调用的 API 规范)
回答by d2vid
You can intercept the JSONPresults that are returned by the google.maps.places.Autocompletefunctionality and use them as you see fit.
您可以拦截google.maps.places.Autocomplete功能返回的JSONP结果,并根据需要使用它们。
Basically you redefine the appendChild method on the head element, and then monitor the javascript elements that the Google autocomplete code inserts into the DOM for JSONP. As javascript elements are added, you override the JSONP callbacks that Google defines in order to get access to the raw autocomplete data.
基本上,您在 head 元素上重新定义 appendChild 方法,然后监视 Google 自动完成代码插入到 JSONP DOM 中的 javascript 元素。添加 javascript 元素后,您会覆盖 Google 定义的 JSONP 回调,以便访问原始自动完成数据。
It's a bit of a hack, here goes (I'm using jQuery but it's not necessary for this hack to work):
这有点像黑客,这里是(我正在使用 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);
};
回答by Alan Hamlett
Use the Places Library from the Google Maps Javascript API: Javascript Places Autocomplete
使用 Google Maps Javascript API 中的 Places 库: Javascript Places Autocomplete
The Places API is different from the Maps API.
Places API 与 Maps API 不同。
回答by Baz1nga
This is a cross domain request. Browsers by default block responses from cross domain sites. You need to use jsonp as the datatyoe. Just google the same and you can see how it can be done using the jquery API. Stack overflow has questions around these too.
这是一个跨域请求。默认情况下,浏览器会阻止来自跨域站点的响应。您需要使用 jsonp 作为 datatyoe。只需 google 相同,您就可以看到如何使用 jquery API 来完成它。堆栈溢出也有这些问题。
Under the same origin policy, a web page served from server1.example.com cannot normally connect to or communicate with a server other than server1.example.com. An exception is the HTML element. Taking advantage of the open policy for elements, some pages use them to retrieve Javascript code that operates on dynamically-generated JSON-formatted data from other origins. This usage pattern is known as JSONP.
在同源策略下,从 server1.example.com 提供的网页无法正常连接到 server1.example.com 以外的服务器或与之通信。一个例外是 HTML 元素。利用元素的开放策略,一些页面使用它们来检索 Javascript 代码,这些代码对来自其他来源的动态生成的 JSON 格式数据进行操作。这种使用模式称为 JSONP。
Note that Google Places is not JSONP compliant so I used the Google Places JavaScript API instead.
请注意,Google Places 不符合 JSONP,因此我改用了 Google Places JavaScript API。
回答by ReX357
You can bypass this issue by using PHP.
您可以使用 PHP 绕过此问题。
In your PHP script use file_get_contents to query the URL like this:
在您的 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')
$suggestions = json_decode(file_get_contents('https://maps.googleapis.com/maps/api/place/autocomplete/json?input=blabla&sensor=false&types=establishment&radius=10000')
You can then just use an AJAX request to your PHP script which will return the results effectively bypassing the cross domain constraint.
然后,您可以只对 PHP 脚本使用 AJAX 请求,该请求将有效地绕过跨域约束返回结果。