iniettare una funzione javascript in un Iframe

Questo collegamento ( versione archiviata ) descrive come inserire codice da uno script in un iframe:

function injectJS() { var iFrameHead = window.frames["myiframe"].document.getElementsByTagName("head")[0]; var myscript = document.createElement('script'); myscript.type = 'text/javascript'; myscript.src = 'myscript.js'; // replace this with your SCRIPT iFrameHead.appendChild(myscript); } 

Va bene, ma cosa succede se voglio inserire un object funzione in un iframe e farlo eseguire nel contesto iframe ? Diciamo che ho:

 function foo () { console.log ("Look at me, executed inside an iframe!", window); } 

e voglio inserire il codice di foo all’interno di un iframe? (la funzione foo potrebbe essere qualcosa caricata dynamicmente, non posso semplicemente racchiuderla tra virgolette )

Ho provato ingenuamente:

var scriptFooString = "" + foo.toString() + ""

per ottenere il codice all’interno della funzione, ma

  • Non so come inserirlo nella testa di iframe (forse con jquery?)
  • Non so se è la strada giusta
  • Non so cosa succede quando la funzione è molto più complessa di quella
  • Non so cosa succede con le virgolette doppie e singole in scriptFooString

Qualche suggerimento?

Prima di tutto puoi farlo solo se il tuo frame e la pagina che lo visualizza si trovano nello stesso dominio (A causa di regole tra domini)

in secondo luogo è ansible manipolare gli oggetti dom e window del frame direttamente tramite JS:

 frames[0].window.foo = function(){ console.log ("Look at me, executed inside an iframe!", window); } 

per ottenere il tuo frame da un object DOMElement puoi usare:

 var myFrame = document.getElementById('myFrame'); myFrame.contentWindow.foo = function(){ console.log ("Look at me, executed inside an iframe!"); } 

Si noti che l’ambito in foo NON è cambiato, quindi la finestra è ancora la finestra genitore ecc. All’interno di foo.

Se si desidera iniettare del codice che deve essere eseguito nel contesto dell’altro frame, è ansible iniettare un tag script o evalarlo:

 frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }'); 

Anche se il consenso generale è quello di non usare mai eval, penso che sia un’alternativa migliore dell’iniezione DOM se hai VERAMENTE bisogno di farlo.

Quindi nel tuo caso specifico potresti fare qualcosa del tipo:

 frames[0].window.eval(foo.toString()); 

Ecco la mia soluzione. Sto usando jquery per inserire il contenuto, quindi usando eval per eseguire i tag script nel contesto di quell’iframe:

  var content = $($.parseHTML(source, document, true)); $("#content").contents().find("html").html(content); var cw = document.getElementById("content").contentWindow; [].forEach.call(cw.document.querySelectorAll("script"), function (el, idx) { cw.eval(el.textContent); });