【问题标题】:Select2 Load Remote Data Not working When URL Changed to Google Address Autocomplete AII当 URL 更改为 Google 地址自动完成 AII 时,Select2 加载远程数据不起作用
【发布时间】:2015-10-12 07:49:49
【问题描述】:

加载时我让这个 Select2 与它提供的示例一起工作

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

但在将 AJAX url 调用替换为 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,但同样的问题!!

【问题讨论】:

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


    【解决方案1】:

    尝试用csrf token添加$.ajaxSetup

    ajax 调用之前:

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

    在你的头部元数据中:

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

    【讨论】:

    • 这个不走运。它适用于您的应用程序吗?后来我将代码移动到一个普通的 index.php 并将它放在服务器中,同样的问题....在 index.php 中,我添加了&lt;?php header("Access-Control-Allow-Origin: *"); ?&gt;。但同样的问题又来了……我想我会在一个单独的输入框中使用谷歌自动完成功能……这已经花了太多时间了。
    【解决方案2】:

    您的问题来自一个名为“CORS”的 HTTP 协议的安全控制,它阻止您对另一个域进行 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);
    

    【讨论】:

      猜你喜欢
      • 2016-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      相关资源
      最近更新 更多