5

Sto cercando di utilizzare un userscript Chrome o uno script Tampermonkey per modificare una pagina con questa struttura:Come posso accedere a un javascript di un iframe da un utente?

<body> 
content up here 

<iframe id="main" src="foo.dat"></iframe> 
</body> 

L'iframe è stessa origine.

Ho bisogno di accedere a una funzione che è in iframe#main. I pensato Potrei usare unsafeWindow per ottenerlo ma continuo a ricevere nulla o undefined restituito.

Ho provato un gran numero di cose:

  • cercato di creare un nuovo elemento script nel iframe, ma attribuisce al genitore anche con $('frame#main').contents().append(script) o $('frame#main').contents()[0].createElement('script')

  • window.frames["#main"].contentWindow rendimenti indefiniti.

Ho provato molte altre cose che non riesco a ricordare in questo momento, ma ho esaurito tutte le mie idee e sento che sto scrivendo spazzatura più di ogni altra cosa che conta.
Non riesco a capire come si gioca con lo unsafeWindow dell'iFrame.

+0

È tutta la stessa origine – Skinner927

risposta

10
  1. unsafeWindow non funziona con frame/iframe su Chrome, Tampermonkey o Firefox.
  2. Cercando di accedere a Global (al frame) JS con jQuery, come quello, non funzionerà.
  3. Gli script di utenti verranno eseguiti su iframe che soddisfano i requisiti @include, e/o @match.

Quindi, è necessario tenere conto delle esecuzioni di più script e quindi si hanno due approcci di base, a seconda di ciò che si sta tentando di realizzare. È possibile:

(A) Adattare lo script a frame specifici, come in this answer.

o (B) iniettare il JS e utilizzare l'oggetto speciale frames per acquisire la funzione specifica desiderata.

Il seguente script mostra entrambi. Installarlo in Tampermonkey (o Firefox Greasemonkey), quindi visitare lo this test page at jsBin.

// ==UserScript== 
// @name  _Calling iframe functions 
// @namespace _pc 
// @include  http://jsbin.com/ugoruz/* 
// @include  http://jsbin.com/okequw/* 
// ==/UserScript== 

console.log ("Script start..."); 

/*--- This next function call will work in Firefox or Tampermonkey ONLY, 
    not pure Chrome userscript. 
*/ 
console.log ("calling functionOfInterest()..."); 
unsafeWindow.functionOfInterest(); 


if (window.top === window.self) { 
    //--- Code to run when page is the main site... 
    console.log ("Userscript is in the MAIN page."); 

    //--- The frames object does not play nice with unsafeWindow. 
    /*--- These next three work in Firefox, but not Tampermonkey, nor pure Chrome. 
    console.log ("1", frames[1].variableOfInterest);    // undefined 
    console.log ("2", unsafeWindow.frames[1].variableOfInterest); // undefined 
    console.log ("3", frames[1].unsafeWindow);      // undefined 
    */ 
    /*--- This next would cause a silent crash, all browsers... 
    console.log ("4", unsafeWindow.frames[1].unsafeWindow.variableOfInterest); 
    */ 

    //--- To get at iFramed JS, we must inject our JS. 
    withPages_jQuery (demoAccessToFramedJS); 
} 
else { 
    //--- Code to run when page is in an iframe... 
    console.log ("Userscript is in the FRAMED page."); 
    console.log ("The frame's ID is:", window.self.frameElement.id); 
} 


function demoAccessToFramedJS ($) { 
    $("body").prepend (
      '<button id="gmMain">Run JS on main window</button>' 
     + '<button id="gmFrame">Run JS on iframe</button>' 
    ); 

    $("#gmMain, #gmFrame").click (function() { 
     if (this.id === "gmMain") { 
      functionOfInterest(); 
     } 
     else { 
      frames[1].functionOfInterest(); 
     } 
     console.log (this.id + "was clicked."); 
    }); 
} 

function withPages_jQuery (NAMED_FunctionToRun) { 
    //--- Use named functions for clarity and debugging... 
    var funcText  = NAMED_FunctionToRun.toString(); 
    var funcName  = funcText.replace (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "$1"); 
    var script   = document.createElement ("script"); 
    script.textContent = funcText + "\n\n"; 
    script.textContent += 'jQuery(document).ready(function() {'+funcName+'(jQuery);});'; 
    document.body.appendChild (script); 
}; 

console.log ("Script end"); 



Vedrete che lo script esegue una funzione sia dalla pagina principale e dal iframe. L'uscita della console (Tampermonkey) sarà:

 
Tampermonkey started 
Script start... 
calling functionOfInterest()... 
Userscript is in the MAIN page. 
Script end 
Tampermonkey started 
Script start... 
calling functionOfInterest()... 
Userscript is in the FRAMED page. 
The frame's ID is: iframe2 
Script end 

Si lavorerà anche come un userscript straight-up Chrome se si rimuove la linea (s) unsafeWindow.

+0

Beh, quello che hai inserito non ha funzionato esattamente per me, ma questo combinato con la tua risposta referenziata ha funzionato. Fondamentalmente, quello che ho finito è stato, come hai suggerito, di includere lo script in entrambi i frame, ma solo eseguirne alcune parti a seconda di dove è stato caricato lo script. Un po 'una soluzione goffa ma a questo punto prenderò qualsiasi cosa. Grazie. – Skinner927