Ce qui provoque 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 vous obtenez l'erreur JavaScript (ou devrait-elle être JScript) "Impossible d'exécuter le code à partir d'un script libéré" – essayez de déplacer toutes les balises méta de la tête afin qu'elles soient avant vos balises de script.

… mais basé sur l'un des commentaires les plus récents sur le blog, la solution que j'ai suggérée peut ne pas fonctionner pour tous. Je pensais que ce serait une bonne ouverture à la communauté StackOverflow ….

Ce qui provoque l'erreur "Impossible d'exécuter du code à partir d'un script libéré" et quelles sont les solutions / solutions de rechange?

Il semble que vous avez frappé un bug / problème dans la façon dont certaines étiquettes sont traitées ou que vous avez des références à des objets publiés sur lesquels vous essayez d'exécuter des méthodes.

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

Ensuite, vérifiez si vous avez des problèmes de page / sécurité abordés ici .

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

Si vous ne savez pas à l'avance si la fenêtre existe encore, vous pouvez essayer / capturer pour la détecter:

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

L'erreur est causée lorsque la fenêtre de script "parent" est disposée (c'est-à-dire fermée), mais une référence au script qui est encore conservé (par exemple dans une autre fenêtre) est invoquée. Même si l'objet est encore en vie, le contexte dans lequel il veut s'exécuter ne l'est pas.

C'est un peu sale, mais ça marche pour mon gadleur Windows Sidebar:

Voici l'idée générale: la fenêtre "principale" met en place une fonction qui évalue un certain code, c'est merveilleux. Ensuite, un «enfant» peut appeler cette «fonction de générateur» (qui est / lié à la portée de la fenêtre principale /) et récupère une fonction qui est également liée à la fenêtre «principale». Un inconvénient évident est, bien sûr, que la fonction de «rebond» ne peut pas se fermer sur la portée, il est apparemment défini dans … de toute façon, assez de gibbering:

Ceci est partiellement pseudo-code, mais j'utilise une variante de celui-ci sur un gadget de la barre latérale de Windows (je continue de le dire parce que les Gadgets de la barre latérale s'exécutent dans la "zone non restreinte 0", qui peut ou peut-être – changer considérablement le scénario).

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

En variante, la fenêtre principale doit 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.

Si vous essayez d'accéder à l'objet JS, la manière la plus simple est de créer une copie:

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

J'espère que cela aidera.

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

Dans 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 original de l'iframe) qui ne sort plus. (Recharger l'iframe a détruit ce contexte.)

Vous pouvez toutefois configurer en toute sécurité des valeurs "sérialisables" (primitives, graphiques d'objets qui ne font pas référence aux fonctions directement) dans la fenêtre parentale. Si vous avez vraiment besoin d'une fenêtre séparée (dans mon cas, un iframe) pour spécifier un travail sur une fenêtre distante, vous pouvez passer le travail en tant que String et "eval" dans le récepteur. Faites attention à cela, cela ne signifie généralement pas une mise en œuvre propre ou sécurisée.

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.

(Ce n'est pas exactement le texte de message d'erreur le plus utile dans le monde.)

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

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

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

J'ai rencontré ce problème lorsque j'étais à 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 essayé d'y accéder après la recharge 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()); 

Ce n'est pas vraiment une réponse, mais plus un exemple d'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 y vivre). Le cadre A ne change jamais, le cadre B change constamment. Nous ne pouvons pas appliquer les changements de code directement dans le cadre A, donc (selon les instructions du vendeur), nous ne pouvons exécuter JavaScript que dans le cadre B – le cadre exact qui continue de changer.

Nous avons un morceau de JavaScript qui doit être exécuté toutes les 5 secondes, de sorte que le JavaScript dans la trame B crée une nouvelle étiquette de script et insère dans la section de tête de la trame B. La configurationInterval existe dans ces nouveaux scripts (celui injecté), comme Ainsi que la fonction à invoquer. Même si le JavaScript injecté est chargé techniquement par l'image A (puisqu'il contient maintenant la balise de script), une fois que l'image B change, la fonction n'est plus accessible par setInterval.

J'ai eu cette erreur dans IE9 dans une page qui finit par ouvrir un iFrame. Tant que iFrame n'était pas ouvert, je pourrais utiliser localStorage. Une fois que l'iFrame a été ouvert et fermé, je n'ai plus pu utiliser le stockage local en raison de cette erreur. Pour le réparer, j'ai dû ajouter ce code dans le Javascript qui se trouvait à l'intérieur de iFrame et aussi à l'aide de localStorage.

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

Cette erreur s'est produite dans DHTMLX tout en ouvrant un dialogue et un identifiant parent ou un identifiant de fenêtre actuel non trouvé

  $(document).ready(function () { if (parent.dxWindowMngr == undefined) return; DhtmlxJS.GetCurrentWindow('wnManageConDlg').show(); }); 

Assurez-vous simplement d'envoyer l'ID de la fenêtre cour / parent correcte tout en ouvrant un dialogue

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

J'ai eu cette erreur en accédant à un événement (cliquez dans mon cas) d'un élément dans la fenêtre principale comme ceci (appelant la fenêtre principale / la plus directe directement):

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

Je l'ai simplement changé comme ça et ça marche bien (appeler 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.