Почему этот рекламный код document.write iframe полностью нарушает Internet Explorer?

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

TL; DR

Предоставленный Google код отслеживания конверсий, который внедрил iframe, используя document.write внезапно заставил страницу перестать выполняться во всех версиях Internet Explorer, но был исправлен путем внедрения одного и того же iframe с использованиемdocument.write метод.

История:

Doubleclick - это рекламная сеть, которая предоставляет фрагмент JavaScript для отслеживания конверсий из рекламы.

Фрагмент, который они дают, выглядит так:

<SCRIPT language="JavaScript">
var axel = Math.random()+"";
var a = axel * 10000000000000;
document.write('<IFRAME SRC="https://fls.doubleclick.net/activityi;src=143;type=donat01;cat=indir4;ord=1;num='+ a + '?" WIDTH=10 HEIGHT=10 FRAMEBORDER=0></IFRAME>');
</SCRIPT>
<NOSCRIPT>
<IFRAME SRC="https://fls.doubleclick.net/activityi;src=143;type=donat01;cat=indir4;ord=1;num=1?"
WIDTH=1 HEIGHT=1 FRAMEBORDER=0></IFRAME>
</NOSCRIPT>

Теперь я знаю, что по разным причинам document.write опасен и его следует избегать. Но Google дает мне этот код, поэтому я решил, что могу доверять ему.

Он неожиданно начал ломать все наши страницы для всех пользователей, использующих Internet Explorer. Например, страница перестает отображаться полностью, как только она document.write, Это было сумасшествие: один из крупнейших сторонних рекламодателей в Интернете дал мне JavaScript, который буквально сломал мои страницы покупок для 25% моего трафика!

В качестве сортировки я быстро заменил тот же код, используя технику внедрения, найденную в Google Analytics:

var iframe = document.createElement('iframe');
iframe.src = //the URL;
iframe.width = 0;
iframe.height = 0;
iframe.frameborder = 0;
var ref = document.getElementsByTagName('script')[0];
ref.parentNode.insertBefore(iframe, ref);

Это решило проблему, фактически не объясняя:

Почему почти пустой iframe, внедренный с помощью document.write, ломает Internet Explorer, но этот метод выше не делает?

6 ответов

Решение

Я решил проблему; оказывается, что это не имеет ничего общего с содержанием <iframe>,

Оказывается, что страница обслуживается платформой, которая начала использовать внутренний анализатор DOM, который по причинам, вероятно, связанным с наличием </ в пределах <script> тег в пределах document.writeполностью удаляет </iframe> закрывающий тег сгенерированной страницы, даже если он сохраняет его в бэкэнде. (Вероятно, он пытается применить правила ETAGO).

Причина, по которой я смог воспроизвести его, заключалась в том, что я копировал сгенерированный document.write код, а не оригинальный код, и никогда не заметил пропавшего </iframe>, (И мой "работающий" код document.write не был удален </iframe> признак того, что проблема заключалась в содержании iframe.)

В результате браузеры разобрали незакрытые <iframe> тег на странице, который Internet Explorer не знал, как с этим справиться, и умер в процессе синтаксического анализа iframe (я до сих пор не совсем уверен, почему).

document.write() блокирует дальнейшую визуализацию страницы до ее завершения. Я предполагаю, что удаленный скрипт загружался некоторое время, и таким образом блокировал загрузку остальной части страницы.

Я также предполагаю, что функция Math.Random() не помогает.

Кроме того... коды отслеживания Google пугают меня... они, как правило, уродливые взломы JavaScript.

Я попытался воспроизвести вашу проблему, но не смог на IE9.

Либо у меня нет правильной настройки теста, либо кажется, что IE до IE 9 имел какую-то ошибку. В Firefox была ошибка simialr: https://bugzilla.mozilla.org/show_bug.cgi?id=293633

Может быть, это сочетание незакрытого iframe и чего-то внутри страницы, которая отображается.

Кажется, у тебя похожая проблема, которая была у меня несколько месяцев назад. document.write запускает и перезаписывает страницу. Просто используйте iframe напрямую, и все должно быть кошерным.

Есть 2 причины, почему первый метод должен быть медленным.

  • document.write () блокирует, пока это фактически не выполнено
  • событие onload окна не срабатывает до тех пор, пока все его iframe и все ресурсы в этих iframe не будут полностью загружены

Ваше решение работает, потому что созданное им iframe не запрашивает удаленный URL до окончания события onload. Установив таймаут для первого кода, вы также получите страницу для загрузки, а затем запрос к удаленному URL.

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

Я не знаю о структуре вашего сайта, но обычно первый скрипт-тег находится в <head>, Iframe в <head> не будет оказано Держу пари, если ты сделал document.body.getElementsByTagName('script')[0] у вас, вероятно, будут проблемы, аналогичные тем, которые вы описали выше.

Другие вопросы по тегам