Почему этот рекламный код document.write iframe полностью нарушает Internet Explorer? - PullRequest
13 голосов
/ 03 июля 2011

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

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 ]

8 голосов
/ 11 июля 2011

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

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

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

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

0 голосов
/ 11 июля 2011

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

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

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

0 голосов
/ 06 июля 2011

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

0 голосов
/ 06 июля 2011

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

0 голосов
/ 05 июля 2011

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

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

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

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

0 голосов
/ 05 июля 2011

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

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

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

...