web-dev-qa-db-fra.com

jQuery/JavaScript: accès au contenu d'une iframe

Je voudrais manipuler le code HTML dans une iframe à l'aide de jQuery.

Je pensais pouvoir le faire en définissant le contexte de la fonction jQuery comme étant le document de l'iframe, comme suit:

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

Cependant, cela ne semble pas fonctionner. Un peu d'inspection me montre que les variables dans frames['nameOfMyIframe'] sont undefined à moins que j'attende le chargement de l'iframe. Cependant, lorsque l'iframe se charge, les variables ne sont pas accessibles (j'obtiens des erreurs de type permission denied-).

Est-ce que quelqu'un connaît un moyen de contourner ce problème?

742
rz.

Je pense que ce que vous faites est soumis à la même politique d'origine . Cela devrait être la raison pour laquelle vous obtenez des erreurs permission denied de type.

362
Onur Bebin

Si le <iframe> provient du même domaine, les éléments sont facilement accessibles en tant que

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

Référence

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

Si l'iframe src provient d'un autre domaine, vous pouvez toujours le faire. Vous devez lire la page externe dans PHP et la renvoyer depuis votre domaine. Comme ça:

iframe_page.php

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

    $domain = file_get_contents($URL)

    echo $domain
?>

Alors quelque chose comme ceci:

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>

L'exemple ci-dessus illustre comment modifier une page externe via une iframe sans l'accès refusé, etc.

41
basysmith

Utilisation

iframe.contentWindow.document

au lieu de

iframe.contentDocument
30
user

Je trouve ça plus propre:

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

Vous devez attacher un événement au gestionnaire onload d'un iframe et exécuter le js qui s'y trouve afin de vous assurer que le chargement de l'iframe est terminé avant de pouvoir y accéder. 

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

Ce qui précède résoudra le problème "pas encore chargé", mais en ce qui concerne les autorisations, si vous chargez une page de l'iframe provenant d'un domaine différent, vous ne pourrez pas y accéder en raison de restrictions de sécurité.

25
Andreas Grech

Vous pouvez utiliser window.postMessage pour appeler une fonction entre page et son iframe (interdomaine ou non).

Documentation

page.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>
19
B.Asselin

Je préfère utiliser une autre variante pour y accéder. Depuis parent, vous pouvez avoir accès à une variable dans iframe enfant. $ est également une variable et vous pouvez avoir accès à son simple appel window.iframe_id.$

Par exemple, window.view.$('div').hide() - masque tous les divs dans iframe avec l'id 'view'

Mais ça ne marche pas en FF. Pour une meilleure compatibilité, vous devriez utiliser

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

4
Evgeny Karpov

Je crée un exemple de code. Maintenant, vous pouvez facilement comprendre à partir de différents domaines que vous ne pouvez pas accéder Contenu de iframe .. Même domaine, nous pouvons accéder au contenu iframe

Je vous partage mon code, veuillez exécuter ce code Vérifiez la console. J'imprime l'image src à la console. Il y a quatre iframe, deux iframe provenant du même domaine et deux autres d'un autre domaine (tiers) .Vous pouvez voir deux images src ( https://www.google.com/logos/doodles/2015/googles-new -logo-5078286822539264.3-hp2x.gif

et

https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif ) sur la console et peut également voir deux erreurs d’autorisation ( 2 Erreur: autorisation refusée d’accéder à la propriété 'document'

... irstChild)}, contenu: fonction (a) {retourne m.nodeName (a, "iframe")? a.contentDocument ...

) qui vient d'un tiers iframe. 

<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>
2
Zisu

Avez-vous essayé le classique en attendant la fin de la charge en utilisant la fonction prête à l'emploi de jQuery?

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

K

2
Khb

Pour encore plus de robustesse:

function getIframeWindow(iframe_object) {
  var doc;

  if (iframe_object.contentWindow) {
    return iframe_object.contentWindow;
  }

  if (iframe_object.window) {
    return iframe_object.window;
  } 

  if (!doc && iframe_object.contentDocument) {
    doc = iframe_object.contentDocument;
  } 

  if (!doc && iframe_object.document) {
    doc = iframe_object.document;
  }

  if (doc && doc.defaultView) {
   return doc.defaultView;
  }

  if (doc && doc.parentWindow) {
    return doc.parentWindow;
  }

  return undefined;
}

et 

...
var frame_win = getIframeWindow( frames['nameOfMyIframe'] );

if (frame_win) {
  $(frame_win.contentDocument || frame_win.document).find('some selector').doStuff();
  ...
}
...
0
Dominique Fortin

Je me suis retrouvé ici à chercher le contenu d'un iframe sans jquery.

document.querySelector('iframe[name=iframename]').contentDocument
0
Jeff Davis

Cette solution fonctionne comme iFrame. J'ai créé un script PHP pouvant extraire tout le contenu de l'autre site Web. Le plus important est que vous pouvez facilement appliquer votre jQuery personnalisé à ce contenu externe. Veuillez vous reporter au script suivant pour obtenir tous les contenus de l’autre site Web, puis vous pourrez également appliquer votre cusom jQuery/JS. Ce contenu peut être utilisé n'importe où, à l'intérieur de tout élément ou de toute page.

<div id='myframe'>

  <?php 
   /* 
    Use below function to display final HTML inside this div
   */

   //Display Frame
   echo displayFrame(); 
  ?>

</div>

<?php

/* 
  Function to display frame from another domain 
*/

function displayFrame()
{
  $webUrl = 'http://[external-web-domain.com]/';

  //Get HTML from the URL
  $content = file_get_contents($webUrl);

  //Add custom JS to returned HTML content
  $customJS = "
  <script>

      /* Here I am writing a sample jQuery to hide the navigation menu
         You can write your own jQuery for this content
      */
    //Hide Navigation bar
    jQuery(\".navbar.navbar-default\").hide();

  </script>";

  //Append Custom JS with HTML
  $html = $content . $customJS;

  //Return customized HTML
  return $html;
}
0
Ahsan Horani