Можно ли использовать API автозаполнения Google Maps/Places через AJAX?

Я пытаюсь использовать API автозаполнения Google Адресов, чтобы предварительно заполнить форму в веб-приложении данными "Установ", чтобы облегчить ввод данных. 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? Кто-нибудь знает обходной путь или какие-то дополнительные параметры, которые я мог бы отправить, чтобы заставить его работать?

Update:

Здесь ссылка на документацию API для этого вызова. В родительских документах даже есть примеры JavaScript JSON-parsing. На самом деле путают, почему это будет закрыто на стороне сервера.

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

Ответ 1

Вот фрагмент кода для будущих читателей, которые сталкиваются с этим сценарием.

Используя "API мест", а не "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" (они выбрали что-то из списка), а затем заполнили входы возвращаемыми данными.

Все это указано на странице Разместить библиотеку Google.

Ответ 2

Чтобы сделать междоменные вызовы AJAX, подобные этому, вы должны использовать JSONP с обратным вызовом. Однако Google не предоставляет интерфейс JSONP для автозаполнения.

Возможно, вы сможете использовать этот класс Autocomplete, хотя, похоже, не существует стиля для выпадающего списка.

РЕДАКТИРОВАТЬ Возможно, это будет способ. Проверьте гео-автозаполнение jQuery-плагина. В нем два демонстрации. Тем не менее, я не рассматривал этот вопрос надлежащим образом.

Ответ 3

Существует два способа доступа к API автозаполнения карт Google.

Первый - через класс google.maps.places.Autocomplete. Это обеспечивает всю необходимую реализацию в Javascript. Однако у вас есть полный контроль над стилем. Используйте классы CSS pac-container и pac-item.

Второе - через Автозаполнение Web-сервиса. Это недоступно через браузер из-за той же политики происхождения (API JSONP не существует). Это самый гибкий способ получить доступ к результатам автозаполнения.

Ответ 4

Google, вероятно, позволяет использовать этот API только через свой собственный Javascript API, который вы загружаете с maps.google.com, который служил файлу Javascript. Отсутствие заголовка Access-Control-Allow-Origin говорит о том, что вы не должны использовать API иначе через Javascript.

В качестве альтернативы вы можете просто написать прокси-сервер на стороне сервера, который вызывает API Google и передает результат на ваш собственный вызов $.getJSON, но это, вероятно, противоречит Условиям обслуживания.

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

(отказ от ответственности: я не читал спецификацию API для этого конкретного вызова функции)

Ответ 5

Вы можете перехватить результаты JSONP, которые возвращаются google.maps.places.Autocomplete и использовать их по своему усмотрению.

В основном вы переопределяете метод appendChild в элементе head, а затем отслеживаете элементы javascript, которые код автозаполнения Google вставляет в DOM для JSONP. По мере добавления элементов javascript вы переопределяете обратные вызовы JSONP, которые определяет Google, чтобы получить доступ к необработанным данным автозаполнения.

Это немного взломать, вот идет (я использую 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);
};

Ответ 6

Это запрос на перекрестный домен. Браузеры по умолчанию блокируют ответы от сайтов с перекрестными доменами. Вы должны использовать jsonp как datatyoe. Просто google тот же, и вы можете увидеть, как это можно сделать с помощью jQuery API. У есть вопросы и вокруг них.

В соответствии с той же политикой происхождения веб-страница, обслуживаемая сервером server1.example.com, не может нормально подключаться к другому серверу, кроме server1.example.com, или взаимодействовать с ним. Исключением является элемент HTML. Используя открытую политику для элементов, некоторые страницы используют их для извлечения кода Javascript, который работает с динамически генерируемыми данными в формате JSON из другого источника. Эта схема использования известна как JSONP.

Обратите внимание, что Google Адреса не совместимы с JSONP, поэтому я использовал API JavaScript для Google Адресов.

Ответ 8

Вы можете обойти эту проблему с помощью PHP.

В вашем PHP script используйте file_get_contents для запроса URL-адреса, например:

$предложения = json_decode (файл_get_contents ('https://maps.googleapis.com/maps/api/place/autocomplete/json?input=blabla&sensor=false&types=establishment&radius=10000')

Затем вы можете просто использовать запрос AJAX для вашего PHP script, который будет эффективно возвращать результаты, минуя ограничение кросс-домена.