Что вызывает ошибку «Невозможно выполнить код из освобожденного скрипта»
-
01-07-2019 - |
Вопрос
Я думал, что нашел решение некоторое время назад (см. блог):
Если вы когда-нибудь получите ошибку JavaScript (или это должен быть JScript) «Невозможно выполнить код из освобожденного скрипта» — попробуйте переместить любые метатеги в заголовке так, чтобы они находились перед тегами вашего скрипта.
...но, судя по одному из последних комментариев в блоге, предложенное мной исправление может подойти не всем.Я подумал, что было бы неплохо открыться сообществу StackOverflow....
Что вызывает ошибку «Невозможно выполнить код из освобожденного сценария» и каковы решения/обходные пути?
Решение
Похоже, вы столкнулись с ошибкой/проблемой в способе обработки некоторых тегов или в том, что у вас есть ссылки на выпущенные объекты, для которых вы пытаетесь выполнить методы.
Сначала я бы переместил любой <meta>
теги перед любыми <script>
теги, как предложено здесь и множество других мест.
Затем проверьте, обсуждались ли у вас проблемы со страницей/безопасностью. здесь.
Другие советы
Эта ошибка возникает при вызове функции, созданной в окне или фрейме, которого больше не существует.
Если вы заранее не знаете, существует ли окно, вы можете попробовать его обнаружить:
try
{
f();
}
catch(e)
{
if (e.number == -2146823277)
// f is no longer available
...
}
Ошибка возникает, когда «родительское» окно скрипта удаляется (т.е.:закрыт), но вызывается ссылка на сценарий, который все еще удерживается (например, в другом окне). Несмотря на то, что «объект» все еще жив, контекст, в котором он хочет выполниться, отсутствует.
Это несколько грязно, но работает для моего гаджета боковой панели Windows:
Вот общая идея:В «главном» окне устанавливается функция, которая будет оценивать некоторый код, да, это так уродливо.Затем «дочерний» может вызвать эту «функцию-конструктор» (которая /привязана к области действия главного окна/) и вернуть функцию, которая также привязана к «главному» окну.Очевидным недостатком, конечно, является то, что функция, являющаяся «отскоком», не может замыкаться в области, в которой она, по-видимому, определена...впрочем, хватит тарабарщины:
Частично это псевдокод, но я использую его вариант в гаджете боковой панели Windows (я продолжаю говорить это, потому что гаджеты боковой панели работают в «неограниченной зоне 0», что может — а может и не — сильно изменить сценарий).
// 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
В качестве варианта главное окно должно иметь возможность передавать функцию functionBuilder дочернему окну - при условии, что функция functionBuilder определена в контексте главного окна!
Мне кажется, что я использовал слишком много слов.ЮММВ.
Если вы пытаетесь получить доступ к объекту JS, самый простой способ — создать копию:
var objectCopy = JSON.parse(JSON.stringify(object));
Надеюсь, это поможет.
Эта ошибка может возникнуть в MSIE, когда дочернее окно пытается связаться с родительским окном, которое больше не открыто.
(Не совсем самый полезный текст сообщения об ошибке в мире.)
Вот очень конкретный случай, в котором я видел такое поведение.У меня это воспроизводится в IE6 и IE7.
Из iframe:
window.parent.mySpecialHandler = function() { ...work... }
Затем, после перезагрузки iframe с новым содержимым, в окне, содержащем iframe:
window.mySpecialHandler();
Этот вызов завершается с ошибкой «Невозможно выполнить код из освобожденного скрипта», поскольку mySpecialHandler был определен в контексте (исходный DOM iframe), из которого больше нет выхода.(Перезагрузка iframe уничтожила этот контекст.)
Однако вы можете безопасно устанавливать «сериализуемые» значения (примитивы, графы объектов, которые не ссылаются непосредственно на функции) в родительском окне.Если вам действительно нужно отдельное окно (в моем случае iframe) для задания некоторой работы удаленному окну, вы можете передать работу как строку и «оценить» ее в получателе.Будьте осторожны с этим, обычно это не обеспечивает чистой и безопасной реализации.
Начиная с IE9, мы начали получать эту ошибку при вызове .getTime() для объекта Date, хранящегося в массиве внутри другого объекта.Решение заключалось в том, чтобы убедиться, что это дата, прежде чем вызывать методы Date:
Неудача: rowTime = wl.rowData[a][12].getTime()
Проходить: rowTime = new Date(wl.rowData[a][12]).getTime()
Я столкнулся с этой проблемой, когда внутри дочернего фрейма я добавил ссылочный тип в окно верхнего уровня и попытался получить к нему доступ после перезагрузки дочернего окна.
то есть
// 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
...
Мне удалось решить проблему, используя только примитивные типы.
// set the value on first load
window.top.timestamp = Number(new Date());
На самом деле это не ответ, а скорее пример того, где именно это происходит.
У нас есть кадр А и кадр Б (это была не моя идея, но мне придется с этим жить).Кадр А никогда не меняется, кадр Б меняется постоянно.Мы не можем применить изменения кода непосредственно к фрейму A, поэтому (в соответствии с инструкциями производителя) мы можем запускать JavaScript только в фрейме B — именно в том фрейме, который постоянно меняется.
У нас есть фрагмент JavaScript, который должен выполняться каждые 5 секунд, поэтому JavaScript в кадре B создает новый тег сценария и вставляет его в заголовок кадра B.В этом новом скрипте (введенном) существует setInterval, а также вызываемая функция.Несмотря на то, что внедренный JavaScript технически загружается кадром A (поскольку он теперь содержит тег сценария), как только кадр B изменится, функция больше не будет доступна через setInterval.
Я получил эту ошибку в IE9 на странице, которая в конечном итоге открывает iFrame.Пока iFrame не был открыт, я мог использовать localStorage.Как только iFrame был открыт и закрыт, я больше не смог использовать localStorage из-за этой ошибки.Чтобы это исправить, мне пришлось добавить этот код в Javascript, который был внутри iFrame, а также использовать localStorage.
if (window.parent) {
localStorage = window.parent.localStorage;
}
получил эту ошибку в DHTMLX при открытии диалога, и идентификатор родителя или идентификатор текущего окна не найден
$(document).ready(function () {
if (parent.dxWindowMngr == undefined) return;
DhtmlxJS.GetCurrentWindow('wnManageConDlg').show();
});
Просто убедитесь, что вы отправляете правильный идентификатор текущего/родительского окна при открытии диалога.
При обновлении источника iframe я получаю эту ошибку.
Получил эту ошибку, получив доступ к событию (щелкните в моем случае) элемента в главном окне следующим образом (вызов главного/крайнего окна напрямую):
top.$("#settings").on("click",function(){
$("#settings_modal").modal("show");
});
Я только что изменил его вот так, и он работает нормально (вызов родителя родительского окна iframe):
$('#settings', window.parent.parent.document).on("click",function(){
$("#settings_modal").modal("show");
});
Мой iframe, содержащий модальное окно, также находится внутри другого iframe.
Объяснения очень актуальны в предыдущих ответах.Просто пытаюсь представить свой сценарий.Надеюсь, это поможет другим.
мы использовали:
<script> window.document.writeln(table) </script>
, и вызов других функций в скрипте на onchange
события, но writeln полностью переопределяет HTML в IE, тогда как в Chrome он ведет себя по-другому.
мы изменили его на:
<script> window.document.body.innerHTML = table;</script>
Таким образом, сохранен сценарий, исправляющий проблему.