Javascript iframe onload this

iFrame onload JavaScript event

I have an iFrame, where I want to send a JavaScript command after loading. My current code looks like this:

 

But with this code the command isn’t executed. What must I change to make it work? Only Chrome and Firefox have to be supported.

Because I am still logged in. If I click on the «Logout» button on the site which will trigger the command I am logged out.

err, you are «logged in»? try:

4 Answers 4

Use the iFrame’s .onload function of JavaScript:

  document.getElementById('my_iframe').onload = function() 

That also doesn’t seem to work:

take a look at this on liveweave.com/9ngqqd i have it working here (try changing the url from the iframe to load some big pages)

document.querySelector("iframe").addEventListener( "load", function(e) < this.style.backgroundColor = "red"; alert(this.nodeName); console.log(e.target); >);

What’s the difference between this way of adding the «load» listener vs the other answer where they set iframe.onload = a function?

@rasen58, they both do exactly the same thing. The advantage of addEventListener is that you can add more than one event listener to the load event. Please refer this answer for more details. stackoverflow.com/a/6348533/9695286

Your code is correct. Just test to ensure it is being called like:

try: function doIt()

Ensure the URL being loaded into the iframe is allowed to be loaded, «check out the output in Chrome Development tools for loading erros». As if it’s not allowed to be loaded the onload event will never be called. When I ran this code the URL «sdsd.com» did not have any restrictions and no loading errors. try it.

Источник

Общение между окнами

Политика «Одинакового источника» (Same Origin) ограничивает доступ окон и фреймов друг к другу.

Идея заключается в том, что если у пользователя открыто две страницы: john-smith.com и gmail.com , то у скрипта со страницы john-smith.com не будет возможности прочитать письма из gmail.com . Таким образом, задача политики «Одинакового источника» – защитить данные пользователя от возможной кражи.

Политика «Одинакового источника»

Два URL имеют «одинаковый источник» в том случае, если они имеют совпадающие протокол, домен и порт.

Эти URL имеют одинаковый источник:

  • http://www.site.com (другой домен: www. важен)
  • http://site.org (другой домен: .org важен)
  • https://site.com (другой протокол: https )
  • http://site.com:8080 (другой порт: 8080 )

Политика «Одинакового источника» говорит, что:

  • если у нас есть ссылка на другой объект window , например, на всплывающее окно, созданное с помощью window.open или на window из и у этого окна тот же источник, то к нему будет полный доступ.
  • в противном случае, если у него другой источник, мы не сможем обращаться к его переменным, объекту document и так далее. Единственное исключение – объект location : его можно изменять (таким образом перенаправляя пользователя). Но нельзя читать location (нельзя узнать, где находится пользователь, чтобы не было никаких утечек информации).

Доступ к содержимому ифрейма

Внутри находится по сути отдельное окно с собственными объектами document и window .

Мы можем обращаться к ним, используя свойства:

  • iframe.contentWindow ссылка на объект window внутри .
  • iframe.contentDocument – ссылка на объект document внутри , короткая запись для iframe.contentWindow.document .

Когда мы обращаемся к встроенному в ифрейм окну, браузер проверяет, имеет ли ифрейм тот же источник. Если это не так, тогда доступ будет запрещён (разрешена лишь запись в location , это исключение).

Для примера давайте попробуем чтение и запись в ифрейм с другим источником:

 catch(e) < alert(e); // Security Error >// также мы не можем прочитать URL страницы в ифрейме try < // Нельзя читать из объекта Location let href = iframe.contentWindow.location.href; // ОШИБКА >catch(e) < alert(e); // Security Error >// . но можно писать в него (и загрузить что-то другое в ифрейм)! iframe.contentWindow.location = '/'; // OK iframe.onload = null; // уберём обработчик, чтобы не срабатывал после изменения location >; 

Код выше выведет ошибку для любых операций, кроме:

  • Получения ссылки на внутренний объект window из iframe.contentWindow
  • Изменения location .

С другой стороны, если у ифрейма тот же источник, то с ним можно делать всё, что угодно:

 ; 

Событие iframe.onload – по сути то же, что и iframe.contentWindow.onload . Оно сработает, когда встроенное окно полностью загрузится со всеми ресурсами.

…Но iframe.onload всегда доступно извне ифрейма, в то время как доступ к iframe.contentWindow.onload разрешён только из окна с тем же источником.

Окна на поддоменах: document.domain

По определению, если у двух URL разный домен, то у них разный источник.

Но если в окнах открыты страницы с поддоменов одного домена 2-го уровня, например john.site.com , peter.site.com и site.com (так что их общий домен site.com ), то можно заставить браузер игнорировать это отличие. Так что браузер сможет считать их пришедшими с одного источника при проверке возможности доступа друг к другу.

Для этого в каждом таком окне нужно запустить:

После этого они смогут взаимодействовать без ограничений. Ещё раз заметим, что это доступно только для страниц с одинаковым доменом второго уровня.

Ифрейм: подождите документ

Когда ифрейм – с того же источника, мы имеем доступ к документу в нём. Но есть подвох. Не связанный с кросс-доменными особенностями, но достаточно важный, чтобы о нём знать.

Когда ифрейм создан, в нём сразу есть документ. Но этот документ – другой, не тот, который в него будет загружен!

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

; 

Нам не следует работать с документом ещё не загруженного ифрейма, так как это не тот документ. Если мы поставим на него обработчики событий – они будут проигнорированы.

Как поймать момент, когда появится правильный документ?

Можно проверять через setInterval :

 < let newDoc = iframe.contentDocument; if (newDoc == oldDoc) return; alert("New document is here!"); clearInterval(timer); // отключим setInterval, он нам больше не нужен >, 100); 

Коллекция window.frames

Другой способ получить объект window из – забрать его из именованной коллекции window.frames :

  • По номеру: window.frames[0] – объект window для первого фрейма в документе.
  • По имени: window.frames.iframeName – объект window для фрейма со свойством name=»iframeName» .
 

Ифрейм может иметь другие ифреймы внутри. Таким образом, объекты window создают иерархию.

Навигация по ним выглядит так:

  • window.frames – коллекция «дочерних» window (для вложенных фреймов).
  • window.parent – ссылка на «родительский» (внешний) window .
  • window.top – ссылка на самого верхнего родителя.
window.frames[0].parent === window; // true

Можно использовать свойство top , чтобы проверять, открыт ли текущий документ внутри ифрейма или нет:

Атрибут ифрейма sandbox

Атрибут sandbox позволяет наложить ограничения на действия внутри , чтобы предотвратить выполнение ненадёжного кода. Атрибут помещает ифрейм в «песочницу», отмечая его как имеющий другой источник и/или накладывая на него дополнительные ограничения.

Существует список «по умолчанию» ограничений, которые накладываются на . Их можно уменьшить, если указать в атрибуте список исключений (специальными ключевыми словами), которые не нужно применять, например: .

Другими словами, если у атрибута «sandbox» нет значения, то браузер применяет максимум ограничений, но через пробел можно указать те из них, которые мы не хотим применять.

allow-same-origin «sandbox» принудительно устанавливает «другой источник» для ифрейма. Другими словами, он заставляет браузер воспринимать iframe , как пришедший из другого источника, даже если src содержит тот же сайт. Со всеми сопутствующими ограничениями для скриптов. Эта опция отключает это ограничение. allow-top-navigation Позволяет ифрейму менять parent.location . allow-forms Позволяет отправлять формы из ифрейма. allow-scripts Позволяет запускать скрипты из ифрейма. allow-popups Позволяет открывать всплывающие окна из ифрейма с помощью window.open .

Пример ниже демонстрирует ифрейм, помещённый в песочницу со стандартным набором ограничений: . На странице содержится JavaScript и форма.

Обратите внимание, что ничего не работает. Таким образом, набор ограничений по умолчанию очень строгий:

Источник

Общение между окнами и фреймами

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/cross-window-communication.

Элемент iframe является обычным узлом DOM, как и любой другой. Существенное отличие – в том, что с ним связан объект window внутреннего окна. Он доступен по ссылке iframe.contentWindow .

Таким образом, iframe.contentWindow.document будет внутренним документом, iframe.contentWindow.document.body – его и так далее.

В старых браузерах использовались другие свойства, такие как iframe.contentDocument и даже iframe.document , но они давно не нужны.

Переход внутрь ифрейма

В примере ниже JavaScript получает документ внутри ифрейма и модифицирует его:

  var iframe = document.getElementsByTagName('iframe')[0]; var iframeDoc = iframe.contentWindow.document; if (iframeDoc.readyState == 'complete') < iframeDoc.body.style.backgroundColor = 'green'; >iframe.onload = function() 

Атрибут src может использовать протокол javascript , как указано выше: src=»javascript:код» . При этом код выполняется и его результат будет содержимым ифрейма. Этот способ описан в стандарте и поддерживается всеми браузерами.

Атрибут src является обязательным, и его отсутствие может привести к проблемам, вплоть до игнорирования ифрейма браузером. Чтобы ничего не загружать в ифрейм, можно указать пустую строку: src=»javascript:»» или специальную страницу: src=»about:blank» .

В некоторых браузерах (Chrome) пример выше покажет iframe зелёным. А в некоторых (Firefox) – оранжевым.

Дело в том, что, когда iframe только создан, документ в нём обычно ещё не загружен.

При обычных значениях iframe src=»https://learn.javascript.ru/» , которые указывают на HTML-страницу (даже если она уже в кеше), это всегда так. Документ, который в iframe на момент срабатывания скрипта iframeDoc – временный, он будет заменён на новый очень скоро. И работать надо уже с новым документом iframeDoc2 – например, по событию iframe.onload .

В случае с javascript -протоколом, по идее, ифрейм уже загружен, и тогда onload у него уже не будет. Но здесь мнения браузеров расходятся, некоторые (Firefox) всё равно «подгрузят» документ позже. Поэтому факт «готовности» документа в скрипте проверяется через iframeDoc.readyState .

Ещё раз заметим, что при обычных URL в качестве src нужно работать не с начальным документом, а с тем, который появится позже.

Кросс-доменность: ограничение доступа к окну

Элемент является «двуличным». С одной стороны, это обычный узел DOM, с другой – внутри находится окно, которое может иметь совершенно другой URL, содержать независимый документ из другого источника.

Внешний документ имеет полный доступ к как к DOM-узлу. А вот к окну – если они с одного источника.

Это приводит к забавным последствиям. Например, чтобы узнать об окончании загрузки , мы можем повесить обработчик iframe.onload . По сути, это то же самое что iframe.contentWindow.onload , но его мы можем поставить лишь в случае, если окно с того же источника.

  

Если бы в примере выше был с текущего сайта, то оба обработчика сработали бы.

Иерархия window.frames

Альтернативный способ доступа к окну ифрейма – это получить его из коллекции window.frames .

Обратим внимание: в коллекции хранится именно окно ( contentWindow ), а не DOM-элемент.

Демонстрация всех способов доступа к окну:

   

Внутри ифрейма могут быть свои вложенные ифреймы. Всё это вместе образует иерархию.

Ссылки для навигации по ней:

  • window.frames – коллекция «детей» (вложенных ифреймов)
  • window.parent – содержит ссылку на родительское окно, позволяет обратиться к нему из ифрейма. Всегда верно:
// (из окна со фреймом) window.frames[0].parent === window; // true
window.frames[0].frames[0].frames[0].top === window

Свойство top позволяет легко проверить, во фрейме ли находится текущий документ:

Песочница sandbox

Атрибут sandbox позволяет построить «песочницу» вокруг ифрейма, запретив ему выполнять ряд действий.

  • Заставляет браузер считать ифрейм загруженным с другого источника, так что он и внешнее окно больше не могут обращаться к переменным друг друга.
  • Отключает формы и скрипты в ифрейме.
  • Запрещает менять parent.location из ифрейма.

Пример ниже загружает в документ с JavaScript и формой. Ни то ни другое не сработает:

Источник

Читайте также:  min-height
Оцените статью