jQuery / JavaScript: доступ к содержимому iframe

Я хотел бы манипулировать HTML внутри iframe с помощью jQuery.

Я думал, что смогу сделать это, установив контекст функции jQuery как документ iframe, что-то вроде:

$(function(){ //document ready
    $('some selector', frames['nameOfMyIframe'].document).doStuff()
});

однако это, похоже, не работает. Немного проверки показывает мне, что переменные в frames['nameOfMyIframe'] are undefined Если я не подожду некоторое время для загрузки iframe. Однако, когда iframe загружает переменные, они недоступны (я получаю permission denied-тип ошибки.)

кто-нибудь знает обходной путь для этого?

11 ответов


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


Если <iframe> из того же домена, элементы легко доступны как

$("#iFrame").contents().find("#someDiv").removeClass("hidden");

ссылка


$(document).ready(function(){
    $('#frameID').load(function(){
        $('#frameID').contents().find('body').html('Hey, i`ve changed content of <body>! Yay!!!');
    });
});

Если iframe src из другого домена, вы все равно можете это сделать. Вам нужно прочитать внешнюю страницу в PHP и повторить ее из вашего домена. Вот так:

iframe_page.в PHP

<?php
    $URL = "http://external.com"

    $domain = file_get_contents($URL)

    echo $domain
?>

затем что-то вроде этого:

display_page.HTML-код

<html>
<head>
  <title>Test</title>
 </head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>

<script>

$(document).ready(function(){   
    cleanit = setInterval ( "cleaning()", 500 );
});

function cleaning(){
    if($('#frametest').contents().find('.selector').html() == "somthing"){
        clearInterval(cleanit);
        $('#selector').contents().find('.Link').html('ideate tech');
    }
}

</script>

<body>
<iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php" ></iframe>
</body>
</html>

выше приведен пример того, как редактировать внешнюю страницу через iframe без отказа в доступе и т. д...


использовать

iframe.contentWindow.document

вместо

iframe.contentDocument

Я нахожу этот способ чище:

var $iframe = $("#iframeID").contents();
$iframe.find('selector');

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

$().ready(function () {
    $("#iframeID").ready(function () { //The function below executes once the iframe has finished loading
        $('some selector', frames['nameOfMyIframe'].document).doStuff();
    });
};

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


Вы можете использовать окно.postMessage для вызова функции между страницей и его iframe (кросс-домен или нет).

документация

страница.HTML-код

<!DOCTYPE html>
<html>
<head>
    <title>Page with an iframe</title>
    <meta charset="UTF-8" />
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script>
    var Page = {
        id:'page',
        variable:'This is the page.'
    };

    $(window).on('message', function(e) {
        var event = e.originalEvent;
        if(window.console) {
            console.log(event);
        }
        alert(event.origin + '\n' + event.data);
    });
    function iframeReady(iframe) {
        if(iframe.contentWindow.postMessage) {
            iframe.contentWindow.postMessage('Hello ' + Page.id, '*');
        }
    }
    </script>
</head>
<body>
    <h1>Page with an iframe</h1>
    <iframe src="iframe.html" onload="iframeReady(this);"></iframe>
</body>
</html>

iframe.HTML-код

<!DOCTYPE html>
<html>
<head>
    <title>iframe</title>
    <meta charset="UTF-8" />
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script>
    var Page = {
        id:'iframe',
        variable:'The iframe.'
    };

    $(window).on('message', function(e) {
        var event = e.originalEvent;
        if(window.console) {
            console.log(event);
        }
        alert(event.origin + '\n' + event.data);
    });
    $(window).on('load', function() {
        if(window.parent.postMessage) {
            window.parent.postMessage('Hello ' + Page.id, '*');
        }
    });
    </script>
</head>
<body>
    <h1>iframe</h1>
    <p>It's the iframe.</p>
</body>
</html>

Я предпочитаю использовать другой вариант для доступа. От родителя вы можете иметь доступ к переменной в дочернем iframe. $ также является переменной, и вы можете получить доступ к ее просто вызову window.iframe_id.$

например, window.view.$('div').hide() - скрыть все divs в iframe с идентификатором "view"

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

$('#iframe_id')[0].contentWindow.$


Я создаю пример кода . Теперь вы можете легко понять из другого домена, к которому вы не можете получить доступ содержание iframe .. Тот же домен, к которому мы можем получить доступ к содержимому iframe

я делюсь с вами своим кодом, пожалуйста, запустите этот код проверьте консоль . Я печатаю картинки в консоли. Есть четыре iframe, два iframe из одного домена и два других из другого домена (третья сторона) .Вы можете видеть две картинки( https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif

и

https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif ) на консоли, а также может видеть две ошибки разрешения( Два Ошибка: отказано в доступе к свойству "document"

...irstChild)}, содержание: функция (a){return m.nodeName (a, "iframe")?а.contentDocument...

), которая идет с третьей стороны фрейма.

<body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top">
<p>iframe from same domain</p>
  <iframe frameborder="0" scrolling="no" width="500" height="500"
   src="iframe.html" name="imgbox" class="iView">

</iframe>
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
   src="iframe2.html" name="imgbox" class="iView1">

</iframe>
<p>iframe from different  domain</p>
 <iframe frameborder="0" scrolling="no" width="500" height="500"
   src="https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif" name="imgbox" class="iView2">

</iframe>

<p>iframe from different  domain</p>
 <iframe frameborder="0" scrolling="no" width="500" height="500"
   src="http://d1rmo5dfr7fx8e.cloudfront.net/" name="imgbox" class="iView3">

</iframe>

<script type='text/javascript'>


$(document).ready(function(){
    setTimeout(function(){


        var src = $('.iView').contents().find(".shrinkToFit").attr('src');
    console.log(src);
         }, 2000);


    setTimeout(function(){


        var src = $('.iView1').contents().find(".shrinkToFit").attr('src');
    console.log(src);
         }, 3000);


    setTimeout(function(){


        var src = $('.iView2').contents().find(".shrinkToFit").attr('src');
    console.log(src);
         }, 3000);

         setTimeout(function(){


        var src = $('.iView3').contents().find("img").attr('src');
    console.log(src);
         }, 3000);


    })


</script>
</body>

вы пробовали классику, ожидая завершения загрузки с помощью встроенной функции jQuery?

$(document).ready(function() {
    $('some selector', frames['nameOfMyIframe'].document).doStuff()
} );

K