2009-08-18 22 views
16

Controllo il contenuto di un iframe incorporato in una pagina da un altro dominio. C'è un modo per javascript nel mio iframe per apportare modifiche al DOM del genitore?<iframe> javascript accede al DOM padre tra domini?

Ad esempio, vorrei che il mio script ifram aggiungesse un gruppo di elementi html al DOM padre. Questo sembra un ordine piuttosto alto - pensieri?

Modifica: Esiste una tecnica denominata "Fragment ID Messaging" che potrebbe essere un modo per comunicare tra iframe tra domini.

Edit: Inoltre, Firefox 3.5, Opera, Chrome (ecc) sembrano essere l'adozione di HTML5 "postMessage" api, che consente la trasmissione dei dati tra domini sicuro tra cornici, iframe e popup. Funziona come un sistema di eventi. IE8 supporta questa funzione, apparentemente, che è forse un po 'sorprendente.

Sommario: No, non è possibile accedere direttamente/modificare il DOM di una pagina da un altro dominio. Ma tu puoi comunicare con lo e può cooperare per apportare le modifiche che desideri.

+0

La risposta attualmente accettata era corretta nel 2009, ma i tempi sono cambiati. Stefan Steiger è migliore e potrebbe valere la pena di cambiare la tua risposta accettata. – Quentin

+0

Grazie a @ Quentin, lo prenderò in considerazione. – aaaidan

risposta

17

Odio dirlo ma sono sicuro al 99% che non stia succedendo direttamente a causa della sicurezza.

Puoi provarlo here.

bhh

+1

Grazie, questo link dimostra il problema molto bene. – aaaidan

+12

PS. Mi hai rovinato la giornata, ma grazie. : P – aaaidan

+3

hey man, è quello che faccio;) –

0

Immagino che correrai a problemi di sicurezza senza usare un proxy. I proxy possono essere molto utili. Si può provare una di quelle:

(1) un PHP based proxy (fate attenzione perché ci sono un sacco di annunci tra link utili)

(2) un Apache .htaccess delega - basta creare una sottodirectory proxy nella vostra di dominio e messo lì un file contenente .htaccess:

RewriteEngine on 
RewriteRule ^(.*)$ http://picasaweb.google.com/$1 [P,L] 

mettere l'altro nome di dominio al posto di picasaweb.google.com

Personalmente io preferisco usare il proxy Apache

+0

Grazie per la tua risposta, warpech. Penso che le mie modifiche abbiano però confuso la mia domanda iniziale, il che mi chiedeva come modificare la dom su una pagina padre all'interno di un iframe di un altro dominio. La risposta breve sembra essere "non puoi". Quindi ora sto esplorando i metodi di comunicazione tra frame e un proxy sul lato server è sicuramente uno di quelli. Grazie! – aaaidan

11

È possibile.

Avevi ragione a menzionare postMessage nelle tue modifiche. Per chi è alla ricerca, esiste un ottimo modo per comunicare in modo javascript compatibile con le versioni precedenti dei domini. Codice breve, facile pure. Soluzione perfetta? Finché è possibile richiedere modifiche al genitore e il bambino:

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

+0

funziona come un fascino. grazie mille –

0

Per AJAX, il server potrebbe restituire l'intestazione Access-Control-Allow-Origin: * per consentire l'accesso tra domini. Forse funziona anche per IFRAME.

+1

no, non è così. Ho appena provato. – Leonardo

5

Sì, è possibile.
È possibile implementare window.postMessage per comunicare tra iframe e/o finestre su domini.
Ma è necessario farlo in modo asincrono.
Se ne hai bisogno in modo sincrono, devi implementare i wrapper attorno a quei metodi asincroni.

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
    <title></title> 

    <!-- 
    <link rel="shortcut icon" href="/favicon.ico"> 


    <link rel="start" href="http://benalman.com/" title="Home"> 

    <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css"> 

    <script type="text/javascript" src="/js/mt.js"></script> 
    --> 
    <script type="text/javascript"> 
     // What browsers support the window.postMessage call now? 
     // IE8 does not allow postMessage across windows/tabs 
     // FF3+, IE8+, Chrome, Safari(5?), Opera10+ 

     function SendMessage() 
     { 
      var win = document.getElementById("ifrmChild").contentWindow; 

      // http://robertnyman.com/2010/03/18/postmessage-in-html5-to-send-messages-between-windows-and-iframes/ 


      // http://stackoverflow.com/questions/16072902/dom-exception-12-for-window-postmessage 
      // Specify origin. Should be a domain or a wildcard "*" 

      if (win == null || !window['postMessage']) 
       alert("oh crap"); 
      else 
       win.postMessage("hello", "*"); 
      //alert("lol"); 
     } 



     function ReceiveMessage(evt) { 
      var message; 
      //if (evt.origin !== "http://robertnyman.com") 
      if (false) { 
       message = 'You ("' + evt.origin + '") are not worthy'; 
      } 
      else { 
       message = 'I got "' + evt.data + '" from "' + evt.origin + '"'; 
      } 

      var ta = document.getElementById("taRecvMessage"); 
      if (ta == null) 
       alert(message); 
      else 
       document.getElementById("taRecvMessage").innerHTML = message; 

      //evt.source.postMessage("thanks, got it ;)", event.origin); 
     } // End Function ReceiveMessage 




     if (!window['postMessage']) 
      alert("oh crap"); 
     else { 
      if (window.addEventListener) { 
       //alert("standards-compliant"); 
       // For standards-compliant web browsers (ie9+) 
       window.addEventListener("message", ReceiveMessage, false); 
      } 
      else { 
       //alert("not standards-compliant (ie8)"); 
       window.attachEvent("onmessage", ReceiveMessage); 
      } 
     } 
    </script> 


</head> 
<body> 

    <iframe id="ifrmChild" src="child.htm" frameborder="0" width="500" height="200" ></iframe> 
    <br /> 


    <input type="button" value="Test" onclick="SendMessage();" /> 

</body> 
</html> 

Child.htm

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
    <title></title> 

    <!-- 
    <link rel="shortcut icon" href="/favicon.ico"> 


    <link rel="start" href="http://benalman.com/" title="Home"> 

    <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css"> 

    <script type="text/javascript" src="/js/mt.js"></script> 
    --> 

    <script type="text/javascript"> 
     /* 
     // Opera 9 supports document.postMessage() 
     // document is wrong 
     window.addEventListener("message", function (e) { 
      //document.getElementById("test").textContent = ; 
      alert(
       e.domain + " said: " + e.data 
       ); 
     }, false); 
     */ 

     // https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage 
     // http://ejohn.org/blog/cross-window-messaging/ 
     // http://benalman.com/projects/jquery-postmessage-plugin/ 
     // http://benalman.com/code/projects/jquery-postmessage/docs/files/jquery-ba-postmessage-js.html 

     // .data – A string holding the message passed from the other window. 
     // .domain (origin?) – The domain name of the window that sent the message. 
     // .uri – The full URI for the window that sent the message. 
     // .source – A reference to the window object of the window that sent the message. 
     function ReceiveMessage(evt) { 
      var message; 
      //if (evt.origin !== "http://robertnyman.com") 
      if(false) 
      { 
       message = 'You ("' + evt.origin + '") are not worthy'; 
      } 
      else 
      { 
       message = 'I got "' + evt.data + '" from "' + evt.origin + '"'; 
      } 

      //alert(evt.source.location.href) 

      var ta = document.getElementById("taRecvMessage"); 
      if(ta == null) 
       alert(message); 
      else 
       document.getElementById("taRecvMessage").innerHTML = message; 

      // http://javascript.info/tutorial/cross-window-messaging-with-postmessage 
      //evt.source.postMessage("thanks, got it", evt.origin); 
      evt.source.postMessage("thanks, got it", "*"); 
     } // End Function ReceiveMessage 




     if (!window['postMessage']) 
      alert("oh crap"); 
     else { 
      if (window.addEventListener) { 
       //alert("standards-compliant"); 
       // For standards-compliant web browsers (ie9+) 
       window.addEventListener("message", ReceiveMessage, false); 
      } 
      else { 
       //alert("not standards-compliant (ie8)"); 
       window.attachEvent("onmessage", ReceiveMessage); 
      } 
     } 
    </script> 


</head> 
<body style="background-color: gray;"> 
    <h1>Test</h1> 

    <textarea id="taRecvMessage" rows="20" cols="20" ></textarea> 

</body> 
</html> 

Qui, si dovrebbe modificare il bambino per inviare postmessages al genitore. ad es. in Child.htm, si fa

window.parent.postMessage("alert(document.location.href); document.location.href = 'http://www.google.com/ncr'", "*"); 

e nel genitore, si fa (in receiveMessage) Non che utilizza eval è insicuro, quindi si dovrebbe invece passare un enum, e chiamare la funzione corrispondente che è necessario mettere sulla pagina madre.

+0

Il caricamento dell'iframe figlio non funzionerà in un ambiente in modalità mista. Ad esempio, la pagina principale in https e la pagina figlio in un iframe (http). – lmiguelmh