Come accedere a Iframe principale da JavaScript


170

Bene, ho un IFrame, che chiama una stessa pagina di dominio. Il mio problema è che voglio accedere ad alcune informazioni da questo Iframe principale da questa pagina chiamata (da JavaScript). Come posso accedere a questo Iframe?

Dettagli: Esistono diversi Iframe come questo, che possono avere la stessa pagina caricata, perché sto programmando un ambiente Windows. Ho intenzione di chiudere questo Iframe, ecco perché devo sapere quale dovrei chiudere dentro di lui. Ho un array che mantiene i riferimenti a questi Iframe.

EDIT: lì iframe sono generati dinamicamente


anche se gli iframe vengono generati in modo dinamico, puoi assegnare un nuovo ID univoco usando una sorta di contatore, infine non devi conoscere l'ID, ma puoi cercare facilmente, vedi la mia risposta.
Akash Kava,

Risposte:


138

Inoltre è possibile impostare nome e ID su valori uguali

<iframe id="frame1" name="frame1" src="any.html"></iframe>

così sarai in grado di usare il prossimo codice all'interno della pagina figlio

parent.document.getElementById(window.name);

16
Forse non è ovvio per tutti, ma con questo metodo è possibile accedere a un oggetto libreria del genitore (solo se il genitore ha già caricato la biblioteca). Esempio: accedi a jQuery con il genitore. $ ('# Qualcosa')
Zsolti,

1
Questa soluzione è compatibile con IE5 + modalità di compatibilità compatibili.
Slayner,

Anche nel 2016, funziona alla grande come parte di una soluzione al problema di IE che stampa i contenuti di un formato iframetroppo piccolo. Ma perché funziona? window.namerestituisce una stringa. Cosa c'è di diverso nell'usare window.nameche passare il nome ID come una stringa che non funziona.)?
Karl,

3
Salve, non funziona con Chrome 59 ..: VM111: 1 DOMException non rilevata: è stato impedito a un frame con origine " xxx " di accedere a un frame con origini incrociate.
Didier68,

Chrome vede i file nella stessa cartella di origine incrociata se non è impostato CORS. Dicono che è per sicurezza. L'impostazione di CORS richiede un server. Invia agli utenti un messaggio per configurare un server o cambiare browser se Chrome viene rilevato.

90

Chiama semplicemente window.frameElementdalla tua pagina incorniciata. Se la pagina non è in una cornice, allora frameElementlo sarànull .

L'altro modo (ottenere l'elemento della finestra all'interno di una cornice è meno banale) ma per completezza:

/**
 * @param f, iframe or frame element
 * @return Window object inside the given frame
 * @effect will append f to document.body if f not yet part of the DOM
 * @see Window.frameElement
 * @usage myFrame.document = getFramedWindow(myFrame).document;
 */
function getFramedWindow(f)
{
    if(f.parentNode == null)
        f = document.body.appendChild(f);
    var w = (f.contentWindow || f.contentDocument);
    if(w && w.nodeType && w.nodeType==9)
        w = (w.defaultView || w.parentWindow);
    return w;
}

2
Grazie! Funziona su IE 6+, FF e Chrome!
Rustyx,

11
window.frameElementritorna nullquando window e iframe hanno domini diversi, ad esempio messaggi di origine incrociata.
Qwerty,

@Qwerty hai trovato qualche soluzione?
Ajay Patidar,

@AjayPatidar Penso di aver rinunciato. :(
Qwerty

78

Consiglierei di usare l' API postMessage .

Nel tuo iframe, chiama:

window.parent.postMessage({message: 'Hello world'}, 'http://localhost/');

Nella pagina includi l'iframe puoi ascoltare eventi come questo:

window.addEventListener('message', function(event) {
      if(event.origin === 'http://localhost/')
      {
        alert('Received message: ' + event.data.message);
      }
      else
      {
        alert('Origin not allowed!');
      }

    }, false);

A proposito, è anche possibile effettuare chiamate verso altre finestre e non solo iframe.

Maggiori informazioni sull'API postMessage sul blog di John Resigs qui


7
Penso che questa sia chiaramente la risposta migliore, i <iframe>contenuti non devono sapere nulla del genitore e viceversa. Devono solo obbedire al semplice contratto di messaggistica. Eccezionale!
Mfeineis,

1
Il <iframe> deve ancora conoscere il dominio del genitore, giusto?
Homr Zodyssey,

1
@HomrZodyssey Il dominio padre è disponibile solo come meccanismo di sicurezza, se non è noto, è possibile impostare '*'.
Amir Ali Akbari,

Utilizzare '*'sui client. Tutte le altre soluzioni danno un errore su un browser Chrome trattando i file nella cartella client come non della stessa origine perché non è stato impostato un server. Questa è la migliore e unica soluzione: dyn-web.com/tutorials/iframes/postmessage

30

Vecchia domanda, ma ho appena avuto lo stesso problema e ho trovato un modo per ottenere l'iframe. Si tratta semplicemente di scorrere attraverso l'array dei frame della finestra principale [] e di testare la finestra del contenuto di ciascun frame rispetto alla finestra in cui è in esecuzione il codice. Esempio:

var arrFrames = parent.document.getElementsByTagName("IFRAME");
for (var i = 0; i < arrFrames.length; i++) {
  if (arrFrames[i].contentWindow === window) alert("yay!");
}

Oppure, usando jQuery:

parent.$("iframe").each(function(iel, el) {
  if(el.contentWindow === window) alert("got it");
});

Questo metodo consente di salvare l'assegnazione di un ID a ciascun iframe, il che è positivo nel tuo caso in quanto sono creati dinamicamente. Non sono riuscito a trovare un modo più diretto, dal momento che non è possibile ottenere l'elemento iframe usando window.parent: va direttamente all'elemento della finestra padre (saltando l'iframe). Quindi il loro ciclo sembra l'unico modo, a meno che tu non voglia usare gli ID.


1
Aggiornamento: questo non ha funzionato esattamente come pubblicizzato, e ho dovuto usare il documento contentWindow.document ===. Non ho idea del perché. Anche in alcuni browser ho usato contentDocument. Bene, mi piace!
Christophe,

1
Chiedo scusa, devo ammetterlo solo su Firefox. :) Comunque ho avuto successo usando il metodo jQuery e contentWindow in più browser.
ingrediente_15939

1
Aggiornamento: ho scoperto che puoi anche usare window.frameElement, ma non sono sicuro di quali browser lo supportino.
Christophe,

2
Non penso che questo tipo di cose funzioni più; viene visualizzato un errore di origine incrociata.
Andrew Mao,

@AndrewMao la domanda riguarda gli stessi documenti di origine, quindi nessun motivo per ottenere problemi di origine incrociata.
Christophe,

21

puoi usare parentper accedere alla pagina principale. Quindi per accedere a una funzione sarebbe:

var obj = parent.getElementById('foo');

1
Kevin, il problema è CONOSCERE l'id. Ho diversi Iframe e voglio accedervi dal codice interno
José Leal,

Ottieni ancora "Bloccato un frame con origine" other-localhost: 8000 "dall'accesso a un frame di origine incrociata."
user2568374,

13

Una volta impostato l'id di iframe, è possibile accedere a iframe dal documento interno come mostrato di seguito.

var iframe = parent.document.getElementById(frameElement.id);

Funziona bene su IE, Chrome e FF.


Sembra un modo contorto di farevar iframe = frameElement
Oriol

frameElement restituisce l'oggetto nel contesto della finestra corrente, ma parent.document.getElementById (frameElement.id) restituisce l'oggetto nel contesto della finestra padre, non è possibile eseguire le funzioni javascript della finestra padre con frameElement, provarlo in jsfiddle e darmi ed esempio se è possibile .
Akash Kava,

6

Forse basta usare

window.parent

nel tuo iframe per ottenere il frame / windows chiamante. Se hai avuto più frame di chiamata, puoi usare

window.top

3

Prova questo, nel tuo frame genitore imposta i tuoi IFRAME in questo modo:

<iframe id="frame1" src="inner.html#frame1"></iframe>
<iframe id="frame2" src="inner.html#frame2"></iframe>
<iframe id="frame3" src="inner.html#frame3"></iframe>

Si noti che l'id di ogni frame viene passato come ancora nell'src.

quindi nel tuo html interno puoi accedere all'ID del frame in cui è caricato tramite location.hash:

<button onclick="alert('I am frame: ' + location.hash.substr(1))">Who Am I?</button>

quindi puoi accedere a parent.document.getElementById () per accedere al tag iframe dall'interno dell'iframe


Sì, questa sarebbe la soluzione più logica, ma a volte ho bisogno di cambiare l'src dell'iframe .. e passando questo parametro hash o GET ogni richiesta non è buona ..
José Leal

perché è male passare l'hash ogni volta? È visibile solo al browser, non al server, e non influisce sulla memorizzazione nella cache come farebbe un parametro get.
Mark Porter,

-1
// just in case some one is searching for a solution
function get_parent_frame_dom_element(win)
{
    win = (win || window);
    var parentJQuery = window.parent.jQuery;
    var ifrms = parentJQuery("iframe.upload_iframe");
    for (var i = 0; i < ifrms.length; i++)
    {
        if (ifrms[i].contentDocument === win.document)
            return ifrms[i];
    }
    return null;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.