当URL更改为Google地址自动完成AII时,选择2加载远程数据不起作用

时间:2015-10-12 07:49:49

标签: google-maps laravel autocomplete laravel-5 jquery-select2

我在加载

时让这个Select2使用它提供的示例

Github用户数据:https://api.github.com/search/repositories

但在更换AJAX网址时不再工作了 Google地址自动填充功能:

https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Vict&types=geocode&language=fr&key=*************************

我的代码:

<select class="js-data-example-ajax">
    <option value="3620194" selected="selected">select2/select2</option>
</select>

<script>
    function formatRepo (repo) {
        if (repo.loading) return repo.text;


        var markup = '<div class="clearfix">' +
                '<div class="col-sm-1">' +
                '<img src="' + repo.owner.avatar_url + '" style="max-width: 100%" />' +
                '</div>' +
                '<div clas="col-sm-10">' +
                '<div class="clearfix">' +
                '<div class="col-sm-6">' + repo.full_name + '</div>' +
                '<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + repo.forks_count + '</div>' +
                '<div class="col-sm-2"><i class="fa fa-star"></i> ' + repo.stargazers_count + '</div>' +
                '</div>';

        if (repo.description) {
            markup += '<div>' + repo.description + '</div>';
        }

        markup += '</div></div>';

        return markup;
    }

    function formatRepoSelection (repo) {
        //return repo.description || repo.text;
        return repo.full_name || repo.text;
    }

    $(document).ready(function(){

        $(".js-data-example-ajax").select2({
            ajax: {
                url: "https://api.github.com/search/repositories",
                dataType: 'json',
                delay: 250,
                data: function (params) {
                    return {
                        q: params.term, // search term
                        page: params.page
                    };
                },
                processResults: function (data, page) {
                    // parse the results into the format expected by Select2.
                    // since we are using custom formatting functions we do not need to
                    // alter the remote JSON data
                    return {
                        results: data.items
                    };
                },
                cache: true
            },
            escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
            minimumInputLength: 1,
            templateResult: formatRepo, // omitted for brevity, see the source of this page
            templateSelection: formatRepoSelection // omitted for brevity, see the source of this page


        });
    });

</script>

显示的错误是:

XMLHttpRequest cannot load https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Vict&types=geocode&language=fr&key=**************************&q=v. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.

集成Google Map Api和Select2的人可以提供帮助吗?我现在不太确定从哪里排除故障......

***我正在Laravel 5中构建我的应用程序 ***我已经尝试过安装barryvdh / laravel-cors,但同样的问题!!

2 个答案:

答案 0 :(得分:0)

尝试使用csrf token添加$.ajaxSetup

在ajax调用之前

$.ajaxSetup({
    headers: {'X-CSRF-Token': $('meta[name=_token]').attr('content')}
});

并在你的头脑中:

<meta name="_token" content="{{ csrf_token() }}"/>

答案 1 :(得分:0)

您的问题来自HTTP协议的安全控制,称为“CORS&#39;谁阻止你对另一个域进行ajax调用,而不是你当前所在的域。

要修复CORS问题,您必须在服务器上实现特定的HEADER。由于Google不属于您,因此无法实现。

因此,要解决此问题,您可以使用Google Api服务并让API为您执行ajax调用。那就是在Select2中你需要使用的不是ajax {url}而是ajax {transport}。

我不确定那部分,但我认为Google API会创建自己的框架是服务站点,并从同一帧执行所有ajax请求,因此CORS不会成为问题。

这是一个有效的例子:

https://jsfiddle.net/sebastienhawkins/b1ws2h07/

$(document).ready(function(){

  $('.placecomplete').placecomplete({
    placeServiceResult:function(data,status){
      console.log(data);
      $('#show_something').html(data.adr_address);
    },
    language:'fr'
  });

});

//jquery.placecomplete.js file content
//! jquery.placecomplete.js
//! version : 0.0.1
//! authors : Sébastien Hawkins
//! license : Apache

(function($){

    if(typeof $.fn.select2 == 'undefined'){
        console.log("ERROR: Placecomplete need Select2 plugin.")
    }
    //Google services
    var ac = null; //Autocomplete
    var ps = null; //Place

    //Google config
    // https://developers.google.com/maps/documentation/javascript/reference#AutocompletionRequest
    var googleAutocompleteOptions = {
        types: ["geocode"]
    };

    //Google init
    window.initGoogleMapsAPI = function(){
        ac = new google.maps.places.AutocompleteService();
        ps = new google.maps.places.PlacesService($('<div/>')[0]); //Google need a mandatory element to pass html result , we do not need this.
    }

    //Google Loading
    if (window.google && google.maps && google.maps.places) {
        window.initGoogleMapsAPI();
    } else {
        $.ajax({
            url: "https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false&callback=initGoogleMapsAPI",
            dataType: "script",
            cache: true
        });
    }

    //Google placeservice result map

    var placeServiceResult = function(data,status){
        var CIVIC = 0, STREET = 1, CITY = 2, SECTEUR = 3, STATE = 4, COUNTRY = 5, ZIPCODE = 6;
        //todo If the result does not have 7 element data map is not the same
        //maybe we will need that html element google put mandatory
        var adrc = data.address_components;
        if(adrc.length != 7) return;

        $('.address input.address').val(adrc[CIVIC].long_name +' '+ adrc[STREET].long_name);
        $('.address input.city').val(adrc[CITY].long_name);
        $('.address input.state').val(adrc[STATE].long_name);
        $('.address input.country').val(adrc[COUNTRY].long_name);
        $('.address input.zipcode').val(adrc[ZIPCODE].long_name);
    }

    //Select2 default options
    var select2DefaultOptions = {
        closeOnSelect: true,
        debug: false,
        dropdownAutoWidth: false,
        //escapeMarkup: Utils.escapeMarkup,
        language: 'en',
        minimumInputLength: 2,
        maximumInputLength: 0,
        maximumSelectionLength: 0,
        minimumResultsForSearch: 0,
        selectOnClose: false,
        theme: 'default',
        width: 'resolve',
        placeholder: {
            id: '-1', // the value of the option
            text: 'Search for address'
        },
        ajax:{
            delay:100
        }
    };

    //jQuery Plugin
    var pluginDefault = {
        placeServiceResult:placeServiceResult
    }
    $.fn.placecomplete = function (options) {
        this.each(function () {
            //Variable by instance
            var $s2 = $(this);

            //Init select2 for $this
            $s2.select2($.extend(true,{
                ajax: {
                    transport: function (params, success, failure) {
                        // is caching enabled?
                        //TODO(sébastien) ajouter le cache pour google autocomplete
                        if ($s2.data('ajax--cache')) {

                        }
                        else {
                            ac.getPlacePredictions($.extend(googleAutocompleteOptions,params.data),success);
                        }
                    },
                    data: function (params) {
                        return {input: params.term };
                    },
                    processResults: function (data, status) {
                        var response = {results:[]}
                        $.each(data,function(index,item){
                            item.text = item.description;
                           response.results.push(item)
                        });
                        return response;
                    }
                }
            }, select2DefaultOptions, options || {} ));

            options = $.extend(true,pluginDefault,options);
            $s2.on('select2:select', function (evt) {
                ps.getDetails({ placeId: evt.params.data.place_id}, options.placeServiceResult);
            });
        });
        return this;
    };

})(jQuery);