Google DFP Refresh Ads удаляет стек window.history в Internet Explorer 10

В настоящее время я работаю разработчиком на сайте, который использует pushstate для перехода между страницами.

На сайте используется объявления Google DFP, которые обновляются при каждом переходе страницы/маршруте.

Я заметил проблему в Internet Explorer

У меня Windows 7, IE10.

googletag.pubads().refresh(GOOGLE_ADS);

Удаляет записи в стеке window.history, что приводит к тому, что при использовании кнопки «Назад» появляются неправильные записи.

Быстрый пример

Добавить записи в стек истории

console.log(window.history.length) // 3

window.history.pushState({}, 'заголовок', '/page_1');
window.history.pushState({}, 'title', '/page_2');
window.history.pushState( {}, 'title', '/page_3');
window.history.pushState({}, 'title', '/page_4');

console.log(window.history.length) // 7

Обновить объявления

googletag.pubads().refresh(GOOGLE_ADS);

Проверить длину истории еще раз

console.log(window.history.length) // 3

Если бы я нажал кнопку «Назад», я бы перешел на страницу перед целевой страницей.

Кто-нибудь еще заметил эту проблему в IE? Глядя на исходный код DFP, он пару раз ссылается на window.history.


person Bodman    schedule 15.05.2013    source источник


Ответы (4)


У меня точно такая же проблема, даже запуск рекламы в iframe с другим доменом все равно приводит к потере истории. Я считаю, что это как-то связано с обработкой IE изменений iframe src как событий истории, но в основном использование объявлений Google полностью нарушает состояние push в IE. Единственный способ, который я нашел, это не использовать рекламу Google.

person mute    schedule 04.06.2013
comment
Да, странно, как это до сих пор не решено. Просто сейчас мы не обновляем рекламу в IE. - person Bodman; 04.06.2013

У нас была точно такая же проблема. В IE10 и IE11 состояние push практически бесполезно, если вы используете DFP.

Тем не менее, мы нашли решение. Это некрасиво, но это работает.

Вместо загрузки объявления мы вставляем iframe. В этом iframe реклама загружается как обычно. Тем не менее, метод refresh() нельзя использовать внутри этого iframe, все равно будет возникать та же проблема. Но что вы можете сделать, когда реклама загружается в iframe, так это обновить весь iframe. При этом реклама будет обновлена, а функциональность pushstate останется неизменной.

Довольно противно, но это работает. Поскольку загружать рекламу в iframe плохо по нескольким причинам, мы делаем это только в IE10 и IE11.

person PeterssonJesper    schedule 05.11.2014

У меня такая же проблема с IE10 и IE11 - очень разочаровывает.

Что бы это ни стоило, я поднял ошибку с Microsoft, которую можно увидеть здесь:

https://connect.microsoft.com/IE/feedbackdetail/view/979564/ie-pushstate-history-is-corrupted-by-google-adsense-google-dpf-doubleclick-for-publishers-advertising

Если у вас есть время, добавьте свои комментарии к ошибке, чтобы придать ей больший вес для возможного исправления.

Адам

person Adam    schedule 23.09.2014
comment
Команда MS ответила запросом PoC, не могли бы вы им ответить? С тех пор никаких действий не предпринималось. - person Artem Russakovskii; 21.01.2015

Как я писал на справочном форуме DFP: https://productforums.google.com/forum/#!topic/dfp/9BsgVtKTU9A

У меня есть рабочее решение, где я использую jQuery.

if(typeof googletag !== 'undefined' && typeof googletag.pubads !== 'undefined') {
   if(adsCloned === false) {
      var $dfpIframe = $('#div-gpt-ad-1477269112222-0').find('iframe'); // this is ad id that you use in googletag.defineSlot()

      $dfpIframe.each(function (i, v) {
         var $clone = $(v).clone();
         $(v).replaceWith($clone);
      });
      adsCloned = true;
   }
   googletag.pubads().refresh();
}

до этого вам нужно определить var adsCloned = false; Причина, по которой это работает, заключается в том, что когда вы обновляете iframe, который вставляется после загрузки страницы (в данном случае клонированный iframe), запись истории не добавляется в IE.

редактировать: если это не сработает для вас, попробуйте удалить if statememt:

if(typeof googletag !== 'undefined' && typeof googletag.pubads !== 'undefined') {
       var $dfpIframe = $('#div-gpt-ad-1477269112222-0').find('iframe'); // this is ad id that you use in googletag.defineSlot()

       $dfpIframe.each(function (i, v) {
          var $clone = $(v).clone();
          $(v).replaceWith($clone);
       });
       googletag.pubads().refresh();
    }

Приведенный выше код не будет работать - моя ошибка. Но рабочее решение для меня - уничтожить всю переменную googletag и снова вызвать весь код.

Первый вызов скрипта dfp выглядит следующим образом (обратите внимание на googletag.pubads().disableInitialLoad(); и gads.id = 'dfpHeadScript';):

// Doubleclick
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
    var gads = document.createElement('script');
    gads.async = true;
    gads.id = 'dfpHeadScript';
    gads.type = 'text/javascript';
    var useSSL = 'https:' == document.location.protocol;
    gads.src = (useSSL ? 'https:' : 'http:') +
        '//www.googletagservices.com/tag/js/gpt.js';
    var node = document.getElementsByTagName('script')[0];
    node.parentNode.insertBefore(gads, node);
})();

googletag.cmd.push(function() {
    enovatis.dfpSlots.push( googletag.defineSlot('...', [240, 400], 'div-gpt-ad-1').addService(googletag.pubads()) );
    enovatis.dfpSlots.push( googletag.defineSlot('...', [[960, 100], [750, 100]], 'div-gpt-ad-2').addService(googletag.pubads()) );

    googletag.pubads().enableSingleRequest();
    googletag.pubads().collapseEmptyDivs();
    googletag.pubads().disableInitialLoad();
    googletag.enableServices();
});

googletag.cmd.push(function(){
    googletag.pubads().refresh();
});

и метод обновления объявлений:

var dfpInterval = null;
var $dfpTop = $('#div-gpt-ad-1');
var $dfpLeft = $('#div-gpt-ad-2');

function refreshDfp() {

    $dfpTop.empty();
    $dfpLeft.empty();

    googletag =  {};
    googletag.cmd = [];

    $('#dfpHeadScript').remove();

    (function() {
        var gads = document.createElement('script');
        gads.async = true;
        gads.id = 'dfpHeadScript';
        gads.type = 'text/javascript';
        var useSSL = 'https:' == document.location.protocol;
        gads.src = (useSSL ? 'https:' : 'http:') +
            '//www.googletagservices.com/tag/js/gpt.js';
        var node = document.getElementsByTagName('script')[0];
        node.parentNode.insertBefore(gads, node);
    })();

    googletag.cmd.push(function() {
        enovatis.dfpSlots.push( googletag.defineSlot('...', [240, 400], 'div-gpt-ad-1').addService(googletag.pubads()) );
        enovatis.dfpSlots.push( googletag.defineSlot('...', [[960, 100], [750, 100]], 'div-gpt-ad-2').addService(googletag.pubads()) );
        googletag.pubads().enableSingleRequest();
        googletag.pubads().collapseEmptyDivs();
        googletag.pubads().disableInitialLoad();
        googletag.enableServices();

        window.clearInterval(dfpInterval);
        dfpInterval = window.setInterval(function(){
            if(typeof googletag.pubads !== 'undefined'){
                window.setTimeout(function(){
                    googletag.pubads().refresh();
                }, 75);
                window.clearInterval(dfpInterval);
            }
        }, 75);
    });
}

Я вызываю его с помощью: refreshDfp.apply(window); и все работает хорошо. Единственным недостатком этого подхода является то, что мы каждый раз отправляем больше запросов в Google.

person nitka.pawel    schedule 29.09.2015