Пользовательский поиск Google - ручная загрузка/выполнение из параметров URL

Получаю какое-то странное поведение от пользовательского поиска Google, которое я не могу понять. Может быть, у кого-то есть ключ.

Я собираю сайт Magento, у которого есть собственная внутренняя поисковая система, но она ограничена только продуктом. Я также хочу реализовать результаты пользовательского поиска Google на странице результатов поиска. Я полагаю, что должен иметь возможность просто выполнить поиск на основе переменных запроса в URL-адресе (чтобы вернуть весь контент, не относящийся к продукту), как таковой:

        <section style="min-height:600px">
            <div style="background-color:#DFDFDF; min-height:800px; width:100%;">
                <div id="cse">Loading</div>
            </div>
        <script src="http://www.google.com/jsapi" type="text/javascript"></script>
        <script type="text/javascript"> 
        //<![CDATA[

            $(document).ready( function(){ 
                console.log('search initiated');
                var t = window.setTimeout( function(){ customSearch(); }, 5000 );
            });

            function customSearch(){
                var q = urlParams()['q'];
                if (q != undefined && q != ""){
                    console.log('q : %s', q); //outputs successfully

                    google.load('search', '1');
                    google.setOnLoadCallback(function () {
                        var customSearchControl = new google.search.CustomSearchControl(MY CUSTOM ID KEY);
                        var cseDrawOptions = new google.search.DrawOptions();
                        cseDrawOptions.setAutoComplete(true); //unknown if this is required... 
                        customSearchControl.draw('cse',cseDrawOptions);                    
                        customSearchControl.execute(q);

                    }, true);

                } 
            }

           function urlParams(){
                    var vars = []; 
                    var hash;
                    var index = window.location.href.indexOf('?');
                    if( index != -1 ){
                        var hashes = window.location.href.slice(index + 1).split('&');
                        for(var i = 0; i < hashes.length; i++){
                            hash = hashes[i].split('=');
                            vars.push(hash[0]);
                            vars[hash[0]] = hash[1].replace(/\+/g, " ");
                        }
                    }
                    return vars;
                }

        //]>
        </script>
        </section>

Замечу, что весь остальной контент я вытащил из логики (но его реализация в magento идентична).

Таким образом, поведение выглядит следующим образом: страница загружается нормально (я задерживаю поиск в Google с тайм-аутом для целей тестирования). Предполагая, что в URL-адресе есть переменная запроса, консоль отслеживает, как и ожидалось. Затем страница просто уничтожается, и Google не возвращает никакого контента. «Уничтожено»… означает, что все элементы на странице исчезают или перезаписываются новой страницей, которую загружает Google. Как будто элемент управления поиском не создает iframe — он просто заменяет страницу HTML-страницей без <body>.

Я подготовил ряд статей на эту тему и просмотрел API. — этот код выглядит так, как будто он должен работать. Но явно не так.

Что мне не хватает?

Ваше здоровье -

ОБНОВЛЕНИЕ

Продолжение возиться с этим показало, что по какой-то причине:

google.load('search', '1');
google.google.setOnLoadCallback( console.log('loaded') )

Была причиной проблемы с замененной страницей. Однако страница с ответом содержала ссылки на модуль поиска, который размещает Google. И если бы я вручную связал эти файлы (избегая google.load), я мог бы запустить поиск, как и ожидалось:

<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script src="http://www.google.com/uds/?file=search&v=1" type="text/javascript"></script>
<script type="text/javascript"> 
//<![CDATA[
  ... search logic

Затем я нашел альтернативный синтаксис на странице разработчиков Google, который, похоже, работал так, как ожидалось:

$(document).ready( function(){ 
        google.load("search", "1", {"callback" : customSearch});
    });

    function customSearch(){
        var q = urlParams()['q'];
        if (q != undefined && q != ""){
            var cseControl = new google.search.CustomSearchControl('MY CUSTOM KEY');

            var cseDrawOptions = new google.search.DrawOptions();
            cseDrawOptions.enableSearchResultsOnly()
            cseControl.draw('cse', cseDrawOptions);
            cseControl.execute(q);
        } 
    }

Что работает, как ожидалось. Единственная реальная проблема на данный момент - это хозяин

Unsafe JavaScript attempt to access frame with URL http://mydomain from frame with URL http://www.google/cse?...

Это сейчас будет брошено.

Я не знаю, как две разные версии синтаксиса загрузки что-то меняют... но, похоже, что-то изменилось. В любом случае, мне неясно, как устранить эти междоменные ошибки.

Мысли было бы здорово.


person Bosworth99    schedule 21.05.2012    source источник
comment
Связано: stackoverflow.com/questions /2298027/   -  person    schedule 29.09.2012


Ответы (1)


Ничего, да?

Ну, я в основном разработал хорошее решение, используя альтернативный метод, который, я думаю, будет более гибким в долгосрочной перспективе. Используя Googles RESTful API и простой вызов jquery .ajax, я могу получить хорошие, контролируемые результаты без междоменных ошибок:

<div id="cse">Loading</div>
<script>
    //https://developers.google.com/custom-search/v1/getting_started
    //https://developers.google.com/custom-search/v1/using_rest#query-params
    //https://developers.google.com/custom-search/v1/cse/list

    var _url    = "https://www.googleapis.com/customsearch/v1";
    var _key    = 'AIzaSy... your api key here'; 
    var _cx     = '001809... your engine id';
    var _q      = urlParams()['q'];                         //query param

    jQuery(document).ready(function() {

        $j.ajax({
            url     : _url,
            type    : 'GET',
            dataType : 'jsonp',
            data :{
                key : _key,
                cx  : _cx,
                q   :_q 
            },
            success     : function(data, textStatus, jqXHR){ responseHandler(data); },
            error       : function(jqXHR, textStatus, errorThrown){ console.log('error: %s'), errorThrown},
            beforeSend  : function(){ console.log('sending request')},
            crossDomain : true
        });

    });

    function responseHandler( response, status) {
        console.log(response);

        var cse = $j('#cse');  // render vars as needed...
        for (var i = 0; i < response.items.length; i++) {
            var item = response.items[i];
            cse.append( "<br>" + item.htmlTitle);
        }
    }

    function urlParams(){
        var vars = []; 
        var hash;
        var index = window.location.href.indexOf('?');
        if( index != -1 ){
            var hashes = window.location.href.slice(index + 1).split('&');
            for(var i = 0; i < hashes.length; i++){
                hash = hashes[i].split('=');
                vars.push(hash[0]);
                vars[hash[0]] = hash[1];
            }
        }
        return vars;
    }

</script>

И ты тоже можешь ;D

Ваше здоровье

person Bosworth99    schedule 22.05.2012