Quelles sont les causes de l'erreur " Impossible d'exécuter du code à partir d'un script libéré"

Je pensais avoir trouvé la solution il y a quelque temps (Voir mon blog ):

Si jamais vous obtenez L'erreur JavaScript (ou devrait-il être JScript) "impossible d'exécuter du code à partir d'un script libéré" - essayez de déplacer les balises meta dans la tête afin qu'elles soient avant vos balises de script.

...mais sur la base de l'un des commentaires les plus récents du blog, le correctif que j'ai suggéré peut ne pas fonctionner pour tout le monde. Je pensais que ce serait un bon pour ouvrir au StackOverflow communauté....

Quelles sont les causes de l'erreur "Impossible d'exécuter du code à partir d'un script libéré" et quelles sont les solutions/solutions de contournement?

54
demandé sur tjrobinson 2008-09-17 17:24:40

12 réponses

On dirait que vous avez rencontré un bug/problème dans la façon dont certaines balises sont gérées ou que vous avez des références à des objets libérés sur lesquels vous essayez d'exécuter des méthodes.

D'abord, je déplacerais toutes les balises <meta> Avant toutes les balises <script>comme suggéré ici et de nombreux autres endroits.

Vérifiez ensuite si vous avez des problèmes de page/Sécurité discutés ici .

19
répondu Joe Skora 2016-12-02 19:05:04

Vous obtenez cette erreur lorsque vous appelez une fonction créée dans une fenêtre ou un cadre qui n'existe plus.

Si vous ne savez pas à l'avance si la fenêtre existe toujours, vous pouvez faire un try/catch pour le détecter:

try
{
  f();
}
catch(e)
{
  if (e.number == -2146823277)
    // f is no longer available
    ...
}
32
répondu Sjoerd Visscher 2008-09-17 15:12:56

L'erreur est causée lorsque la fenêtre' parent ' du script est éliminée (c'est-à-dire: fermée) mais une référence au script qui est toujours conservée (comme dans une autre fenêtre) est invoquée. Même si l '"objet" est toujours vivant, le contexte dans lequel il veut s'Exécuter ne l'est pas.

C'est un peu sale, mais cela fonctionne pour mon Gadget Windows Sidebar:

Voici l'idée générale: La fenêtre 'main' met en place une fonction qui éval'uate du code, Ouaip, c'est si moche. Ensuite, un enfant peut appelez cette "fonction builder" (qui est / liée à la portée de la fenêtre principale/) et récupérez une fonction qui est également liée à la fenêtre' main'. Un inconvénient évident est, bien sûr, que la fonction étant "rebond" ne peut pas fermer sur la portée dans laquelle elle est apparemment définie... quoi qu'il en soit, assez de gibbering:

C'est partiellement du pseudo-code, mais j'en utilise une variante sur un Gadget Windows Sidebar (je continue à le dire parce que les Gadgets Sidebar fonctionnent dans "zone 0 sans restriction", ce qui peut -- ou peut ne pas-changer le scénario grandement.)


// 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

Comme variante, la fenêtre principale devrait pouvoir passer la fonction functionBuilder à la fenêtre enfant-tant que la fonction functionBuilder est définie dans le contexte de la fenêtre principale!

J'ai l'impression d'avoir utilisé trop de mots. YMMV.

17
répondu 2010-04-16 00:00:59

Si vous essayez d'accéder à L'objet JS, le plus simple est de créer une copie:

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

Espère que ça vous aidera.

8
répondu Grzegorz Ciwoniuk 2014-02-25 16:32:31

Voici un cas très spécifique dans lequel j'ai vu ce comportement. Il est reproductible pour moi dans IE6 et IE7.

Depuis un iframe:

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

Ensuite, après avoir rechargé l'iframe avec un nouveau contenu, dans la fenêtre contenant l'iframe:

window.mySpecialHandler();

Cet appel échoue avec "impossible d'exécuter du code à partir d'un script libéré" car mySpecialHandler a été défini dans un contexte (le DOM d'origine de l'iframe) qui ne se termine plus. (Le rechargement de l'iframe a détruit ce contexte.)

Vous pouvez cependant, définissez en toute sécurité des valeurs "sérialisables" (primitives, graphiques d'objets qui ne référencent pas directement les fonctions) dans la fenêtre parent. Si vous avez vraiment besoin d'une fenêtre séparée (dans mon cas, un iframe) pour spécifier un travail dans une fenêtre distante, vous pouvez passer le travail sous forme de chaîne et le "eval" dans le récepteur. Soyez prudent avec cela, il ne fait généralement pas pour une implémentation propre ou sécurisée.

6
répondu aaron 2010-05-10 22:50:25

À partir de IE9, nous avons commencé à recevoir cette erreur lors de l'appel .getTime() sur un objet Date stocké dans un tableau dans un autre objet. La solution était de s'assurer que c'était une Date avant d'appeler les méthodes Date:

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

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

5
répondu Tom 2016-12-02 19:06:04

Cette erreur peut se produire dans MSIE lorsqu'une fenêtre enfant tente de communiquer avec une fenêtre parent qui n'est plus ouverte.

(pas exactement le texte de message d'erreur le plus utile au monde.)

3
répondu pcorcoran 2008-09-17 14:02:32

J'ai rencontré ce problème quand à l'intérieur d'un cadre enfant j'ai ajouté un type de référence à la fenêtre de niveau supérieur et j'ai tenté d'y accéder après le rechargement de la fenêtre enfant

C'est-à-dire

// 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
...

J'ai pu résoudre le problème en utilisant uniquement des types primitifs

// set the value on first load
window.top.timestamp = Number(new Date());
2
répondu wycleffsean 2013-05-30 19:19:12

Ce n'est pas vraiment une réponse, mais plus un exemple de l'endroit où cela se produit précisément.

Nous avons le cadre A et le cadre B (ce n'était pas mon idée, mais je dois vivre avec). L'image A ne change jamais, L'image B change constamment. Nous ne pouvons pas appliquer les modifications de code directement dans l'image A, donc (selon les instructions du fournisseur) nous ne pouvons exécuter JavaScript que dans l'image B - l'image exacte qui change constamment.

Nous avons un morceau de JavaScript qui doit s'exécuter toutes les 5 secondes, donc le JavaScript dans le cadre B créez une nouvelle balise de script et insérez-la dans la section head de l'image B. Le setInterval existe dans ces nouveaux scripts (celui injecté), ainsi que la fonction à invoquer. Même si le JavaScript injecté est techniquement chargé par l'image a (puisqu'il contient maintenant la balise script), une fois que l'image B change, la fonction n'est plus accessible par setInterval.

1
répondu Nathan Crause 2012-04-29 03:26:42

J'ai eu cette erreur dans IE9 dans une page qui ouvre finalement un iFrame. Tant que l'iFrame n'était pas ouvert, je pourrais utiliser localStorage. Une fois l'iFrame ouvert et fermé, je n'ai plus pu utiliser localStorage à cause de cette erreur. Pour le réparer, j'ai dû ajouter ce code dans le Javascript qui était à l'intérieur de l'iFrame et aussi en utilisant le localStorage.

if (window.parent) {
    localStorage = window.parent.localStorage;
}
0
répondu Melanie 2013-04-12 13:54:53

A obtenu cette erreur dans DHTMLX lors de l'ouverture d'un dialogue et d'un ID parent ou d'un ID de fenêtre actuel introuvable

        $(document).ready(function () {

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

});

Assurez-vous simplement d'envoyer l'id de fenêtre curr/parent correct lors de l'ouverture d'un dialogue

0
répondu panky sharma 2015-05-14 05:39:26

Lors de la mise à jour du src d'iframe, je reçois cette erreur.

A obtenu cette erreur en accédant à un événement(cliquez dans mon cas) d'un élément dans la fenêtre principale comme ceci (en appelant directement la fenêtre principale/extérieure):

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

Je viens de le changer comme ceci et cela fonctionne bien (en appelant le parent du parent de la fenêtre iframe):

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

Mon iframe contenant le modal est également dans un autre iframe.

0
répondu Chan 2017-06-13 09:50:29