Что вызывает ошибку «Невозможно выполнить код из освобожденного скрипта»

StackOverflow https://stackoverflow.com/questions/83132

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

Таким образом, сохранен сценарий, исправляющий проблему.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top