it-swarm.it

Cosa causa l'errore "Impossibile eseguire il codice da uno script liberato"

Ho pensato di aver trovato la soluzione qualche tempo fa (vedi il mio blog ):

Se ottieni mai l'errore JavaScript (o dovrebbe essere JScript) "Impossibile eseguire codice da uno script liberato" - prova a spostare i meta tag in testa in modo che siano prima dei tag di script. 

... ma sulla base di uno dei più recenti commenti del blog, la correzione che ho suggerito potrebbe non funzionare per tutti. Ho pensato che sarebbe stato un buon modo per aprirmi alla community di StackOverflow ....

Cosa causa l'errore "Impossibile eseguire il codice da uno script liberato" e quali sono le soluzioni/soluzioni alternative?

57
Tom Robinson

Sembra che tu abbia riscontrato un bug/problema nel modo in cui alcuni tag sono gestiti o che tu abbia riferimenti ad oggetti rilasciati su cui stai provando ad eseguire metodi.

Innanzitutto sposterei qualsiasi tag <meta> prima di qualsiasi tag <script> come suggerito here e numerosi altri posti.

Quindi controlla se hai problemi relativi alla pagina/sicurezza discussi qui .

19
Joe Skora

Si ottiene questo errore quando si chiama una funzione creata in una finestra o frame che non esiste più. 

Se non sai in anticipo se la finestra esiste ancora, puoi provare/catturare per rilevarlo:

try
{
  f();
}
catch(e)
{
  if (e.number == -2146823277)
    // f is no longer available
    ...
}
33
Sjoerd Visscher

L'errore si verifica quando viene eliminata la finestra di script "padre" (vale a dire: chiusa) ma viene richiamato un riferimento allo script che è ancora conservato (come in un'altra finestra). Anche se l'oggetto è ancora vivo, il contesto in cui vuole essere eseguito non lo è.

È un po 'sporco, ma funziona per il mio Windows Sidebar Gadget:

Ecco l'idea generale: La finestra 'principale' imposta una funzione che valuterà il codice, sì, è così brutto . Quindi un 'figlio' può chiamare questa "funzione costruttore" (che è/associato all'ambito della finestra principale /) e recupera una funzione che è anche vincolata alla finestra 'principale'. Un ovvio svantaggio è, naturalmente, che la funzione "rimbalzo" non può chiudere il campo di applicazione apparentemente definito in ... comunque, abbastanza del gibbering:

Questo è parzialmente pseudo-codice, ma io uso una variante di esso su un Windows Sidebar Gadget (continuo a dirlo perché i gadget Sidebar vengono eseguiti nella "zona senza restrizioni 0", che potrebbe - o potrebbe non - cambiare molto lo scenario).


// This has to be setup from the main window, not a child/etc!
mainWindow.functionBuilder = function (func, args) {
  // trim the name, if any
  var funcStr = ("" + func).replace(/^function\s+[^\s(]+\s*\(/, "function (")
  try {
    var rebuilt
    eval("rebuilt = (" + funcStr + ")")
    return rebuilt(args)
  } catch (e) {
    alert("oops! " + e.message)
  }
}

// then in the child, as an example
// as stated above, even though function (args) looks like it's 
// a closure in the child scope, IT IS NOT. There you go :)
var x = {blerg: 2}
functionInMainWindowContenxt = mainWindow.functionBuilder(function (args) {
  // in here args is in the bound scope -- have at the child objects! :-/
  function fn (blah) {
    return blah * args.blerg
  }
  return fn
}, x)

x.blerg = 7
functionInMainWindowContext(6) // -> 42 if I did my math right

Come variante, la finestra principale dovrebbe essere in grado di passare la funzione functionBuilder alla finestra figlio - purché la funzione functionBuilder sia definita nel contesto della finestra principale!

Mi sento come se avessi usato troppe parole. YMMV.

18
user166390

Se stai tentando di accedere all'oggetto JS, il modo più semplice è creare una copia:

var objectCopy = JSON.parse(JSON.stringify(object));

Spero che ti possa aiutare.

8

Ecco un caso molto specifico in cui ho visto questo comportamento. È riproducibile per me in IE6 e IE7.

Da dentro un iframe:

window.parent.mySpecialHandler = function() { ...work... }

Quindi, dopo aver ricaricato l'iframe con nuovi contenuti, nella finestra contenente l'iframe:

window.mySpecialHandler();

Questa chiamata non riesce con "Impossibile eseguire il codice da uno script liberato" perché mySpecialHandler è stato definito in un contesto (il DOM originale dell'iframe) che non esce più. (Ricaricare l'iframe ha distrutto questo contesto.)

È tuttavia possibile impostare in modo sicuro valori "serializzabili" (primitive, grafici di oggetti che non fanno riferimento direttamente alle funzioni) nella finestra padre. Se hai davvero bisogno di una finestra separata (nel mio caso, un iframe) per specificare del lavoro su una finestra remota, puoi passare il lavoro come una stringa e "valutarla" nel ricevitore. Prestare attenzione a questo, in genere non rende un'implementazione pulita o sicura.

6
aaron

A partire da IE9 abbiamo iniziato a ricevere questo errore durante la chiamata di .getTime () su un oggetto Date memorizzato in una matrice all'interno di un altro oggetto. La soluzione era assicurarsi che fosse una data prima di chiamare i metodi di data:

Fail: rowTime = wl.rowData[a][12].getTime()

Passa: rowTime = new Date(wl.rowData[a][12]).getTime()

5
Tom

Questo errore può verificarsi in MSIE quando una finestra secondaria tenta di comunicare con una finestra padre che non è più aperta.

(Non è esattamente il testo del messaggio di errore più utile al mondo.)

3
pcorcoran

Ho incontrato questo problema quando all'interno di un frame secondario ho aggiunto un tipo di riferimento alla finestra di livello superiore e ho tentato di accedervi dopo la finestra secondaria ricaricata

cioè.

// set the value on first load
window.top.timestamp = new Date();

// after frame reloads, try to access the value
if(window.top.timestamp) // <--- Raises exception
...

Sono stato in grado di risolvere il problema utilizzando solo tipi primitivi

// set the value on first load
window.top.timestamp = Number(new Date());
2
wycleffsean

Questa non è davvero una risposta, ma più un esempio di dove questo accade esattamente.

Abbiamo il frame A e il frame B (questa non era la mia idea, ma devo conviverci). Il frame A non cambia mai, Frame B cambia costantemente. Non possiamo applicare le modifiche al codice direttamente nel frame A, quindi (secondo le istruzioni del fornitore) possiamo solo eseguire JavaScript nel frame B, il frame esatto che continua a cambiare.

Abbiamo un pezzo di JavaScript che deve essere eseguito ogni 5 secondi, quindi il JavaScript nel frame B crea un nuovo tag script e inserisce nella sezione head del frame B. Il setInterval esiste in questi nuovi script (quello iniettato), come bene come la funzione da invocare. Anche se il JavaScript iniettato viene tecnicamente caricato dal frame A (poiché ora contiene il tag script), una volta modificato il frame B, la funzione non è più accessibile da setInterval.

1
Nathan Crause

Ho ricevuto questo errore in IE9 all'interno di una pagina che alla fine apre un iFrame. Finché l'iFrame non era aperto, potrei usare localStorage. Una volta che iFrame è stato aperto e chiuso, non ero più in grado di utilizzare localStorage a causa di questo errore. Per risolvere il problema, ho dovuto aggiungere questo codice al Javascript che si trovava all'interno di iFrame e che utilizzava anche localStorage.

if (window.parent) {
    localStorage = window.parent.localStorage;
}
0
Melanie

All'aggiornamento di src di iframe sto ricevendo quell'errore.

Ottenuto quell'errore accedendo ad un evento (clicca nel mio caso) di un elemento nella finestra principale come questo (chiamando direttamente la finestra principale/esterna): 

top.$("#settings").on("click",function(){
    $("#settings_modal").modal("show");
}); 

L'ho appena modificato in questo modo e funziona correttamente (chiamando il genitore del genitore della finestra iframe):

$('#settings', window.parent.parent.document).on("click",function(){                    
   $("#settings_modal").modal("show");      
});

Il mio iframe contenente il modal si trova anche all'interno di un altro iframe.

0
Chan

Le spiegazioni sono molto pertinenti nelle risposte precedenti. Sto solo cercando di fornire il mio scenario. Spero che questo possa aiutare gli altri.

stavamo usando:

<script> window.document.writeln(table) </script>

e chiama altre funzioni nello script su eventi onchange ma writeln ignora completamente l'HTML in IE dove ha un comportamento diverso in chrome.

lo abbiamo cambiato in:

<script> window.document.body.innerHTML = table;</script> 

Così ha mantenuto il copione che ha risolto il problema.

0
pavan kumar

ha ottenuto questo errore in DHTMLX durante l'apertura di un dialogo e l'id genitore o l'id attuale della finestra non trovato 

        $(document).ready(function () {

            if (parent.dxWindowMngr == undefined) return;
            DhtmlxJS.GetCurrentWindow('wnManageConDlg').show();

});

Assicurati di inviare l'id della finestra curr/parent corretta durante l'apertura di un dialogo

0
panky sharma