Почему этот 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, который LITERALLY сломал мои страницы покупок на 25% моего трафика!
Как triage, я быстро заменил в том же коде, используя метод инъекций, найденный в 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, но этот метод выше не работает?
Ответы
Ответ 1
Я решил проблему; оказывается, что это не имеет никакого отношения к содержимому <iframe>
.
Оказывается, страница обслуживается инфраструктурой, которая начала использовать парсерный DOM-парсер, который по причинам, связанным с наличием </
в теге <script>
в document.write
, полностью удаляет </iframe
> закрывающий тег с созданной страницы, хотя он сохраняет его в бэкэнд. (Вероятно, он пытается обеспечить соблюдение правил ETAGO).
Причина, по которой я смог воспроизвести ее, заключалась в том, что я копировал сгенерированный код document.write
, а не оригинальный код, и никогда не замечал отсутствующий </iframe>
. (И мой "действующий" document.write-код не имел вырезанного тега </iframe>
, что заставило меня поверить, что проблема была в содержании iframe
.)
В результате браузеры проанализировали незакрытый тег <iframe>
на странице, который Internet Explorer не знал, как обрабатывать, и умер частично через синтаксический разбор iframe (я все еще не совсем уверен, почему),
Ответ 2
document.write()
блокирует дальнейшее отображение страницы до тех пор, пока она не завершится. Я предполагаю, что удаленный script занимает некоторое время, чтобы загрузить, и таким образом блокирует остальную страницу от загрузки.
Я также предполагаю, что функция Math.Random() не помогает.
Также... Коды отслеживания Google пугают меня... они, как правило, уродливые хаки javascript.
Ответ 3
Есть две причины, почему первый метод должен быть медленным.
- document.write() блокируется до фактического выполнения
- Событие onload не запускается до тех пор, пока все его фреймы и все ресурсы в этих iframes не будут полностью загружены.
Ваше решение работает, потому что iframe, который он создает, не запрашивает удаленный URL-адрес до момента события onload. Имея заданный тайм-аут для первого кода, вы также получите загрузку страницы, а затем запрос на удаленный URL-адрес для запуска.
Что касается того, почему смена кода сломала сайт, я не могу найти никаких различий в скорости между ними. Возможно, это было быстрее, потому что оно было кэшировано.
Ответ 4
Я не знаю о структуре вашего сайта, но обычно первый тег script находится в <head>
. Iframe в <head>
не будет отображаться. Я сделаю ставку, если вы сделали document.body.getElementsByTagName('script')[0]
, у вас, вероятно, были бы похожие проблемы с тем, что вы описали выше.
Ответ 5
Кажется, у вас такая же проблема, что У меня было несколько месяцев назад. document.write
запускает и перезаписывает страницу. Просто используйте iframe
напрямую, и все должно быть кошерным.
Ответ 6
Я попытался реплицировать вашу проблему, но не смог на IE9.
Либо у меня нет правильной тестовой установки, либо кажется, что IE до IE 9 имел некоторую ошибку. Firefox имел ошибку simialr: https://bugzilla.mozilla.org/show_bug.cgi?id=293633
Возможно, это комбинация незакрытого iframe и что-то внутри отображаемой страницы.