"해제된 스크립트에서 코드를 실행할 수 없습니다" 오류의 원인

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

  •  01-07-2019
  •  | 
  •  

문제

나는 얼마 전에 해결책을 찾았다고 생각했습니다. 블로그):

JavaScript(또는 JScript여야 함) 오류 "해제된 스크립트에서 코드를 실행할 수 없습니다"가 발생하는 경우 헤드에 있는 메타 태그를 스크립트 태그 앞에 오도록 이동해 보세요.

...하지만 가장 최근 블로그 댓글 중 하나에 따르면 제가 제안한 수정 사항이 모든 사람에게 적용되지 않을 수도 있습니다.나는 이것이 StackOverflow 커뮤니티에 공개하기에 좋은 것이라고 생각했습니다....

"해제된 스크립트에서 코드를 실행할 수 없습니다" 오류의 원인은 무엇이며 해결 방법은 무엇입니까?

도움이 되었습니까?

해결책

일부 태그가 처리되는 방식에 버그/문제가 발생한 것 같거나 메소드를 실행하려고 하는 릴리스된 객체에 대한 참조가 있는 것 같습니다.

먼저 무엇이든 옮기겠습니다. <meta> 태그 앞에 <script> 제안된 태그 여기 그리고 수많은 다른 장소들.

그런 다음 논의된 페이지/보안 문제가 있는지 확인하세요. 여기.

다른 팁

더 이상 존재하지 않는 창이나 프레임에서 생성된 함수를 호출하면 이 오류가 발생합니다.

창이 여전히 존재하는지 미리 알 수 없는 경우 try/catch를 수행하여 이를 감지할 수 있습니다.

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 함수를 전달할 수 있어야 합니다!

제가 너무 단어를 많이 사용한 것 같습니다.YMMV.

JS 객체에 액세스하려는 경우 가장 쉬운 방법은 복사본을 만드는 것입니다.

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

도움이 되길 바랍니다.

이 오류는 하위 창이 더 이상 열려 있지 않은 상위 ​​창과 통신을 시도할 때 MSIE에서 발생할 수 있습니다.

(세상에서 가장 유용한 오류 메시지 텍스트는 아닙니다.)

다음은 제가 이 동작을 본 매우 구체적인 사례입니다.IE6 및 IE7에서 재현 가능합니다.

iframe 내에서:

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

그런 다음 새 콘텐츠로 iframe을 다시 로드한 후 iframe이 포함된 창에서 다음을 수행합니다.

window.mySpecialHandler();

mySpecialHandler가 더 이상 종료되지 않는 컨텍스트(iframe의 원래 DOM)에 정의되었기 때문에 이 호출은 "해제된 스크립트에서 코드를 실행할 수 없습니다"라는 메시지와 함께 실패합니다.(iframe을 다시 로드하면 이 컨텍스트가 파괴됩니다.)

그러나 상위 창에서 "직렬화 가능한" 값(기본값, 함수를 직접 참조하지 않는 개체 그래프)을 안전하게 설정할 수 있습니다.원격 창에 일부 작업을 지정하기 위해 별도의 창(제 경우에는 iframe)이 정말로 필요한 경우 해당 작업을 문자열로 전달하고 수신자에서 "평가"할 수 있습니다.일반적으로 깨끗하거나 안전한 구현이 불가능하므로 주의하세요.

IE9부터 다른 객체 내의 배열에 저장된 Date 객체에 대해 .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와 프레임 B를 가지고 있습니다(이것은 내 생각은 아니지만 계속해서 따라가야 합니다).프레임 A는 절대 변하지 않고, 프레임 B는 끊임없이 변합니다.코드 변경 사항을 프레임 A에 직접 적용할 수 없으므로 (공급업체의 지침에 따라) 계속 변경되는 정확한 프레임인 프레임 B에서만 JavaScript를 실행할 수 있습니다.

5초마다 실행해야 하는 JavaScript가 있으므로 프레임 B의 JavaScript는 새 스크립트 태그를 생성하고 프레임 B의 헤드 섹션에 삽입합니다.setInterval은 이 새 스크립트(주입된 스크립트)와 호출할 함수에 존재합니다.주입된 JavaScript가 기술적으로 프레임 A에 의해 로드되더라도(이제 스크립트 태그가 포함되어 있으므로) 프레임 B가 변경되면 해당 함수는 더 이상 setInterval을 통해 액세스할 수 없습니다.

결국 iFrame을 여는 페이지 내의 IE9에서 이 오류가 발생했습니다.iFrame이 열려 있지 않은 한 localStorage를 사용할 수 있습니다.iFrame을 열고 닫으면 이 오류로 인해 더 이상 localStorage를 사용할 수 없습니다.이 문제를 해결하려면 iFrame 내부에 있는 Javascript에 이 코드를 추가하고 localStorage도 사용해야 했습니다.

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

대화 상자를 여는 동안 DHTMLX에서 이 오류가 발생했으며 상위 ID 또는 현재 창 ID를 찾을 수 없습니다.

        $(document).ready(function () {

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

});

대화를 여는 동안 올바른 현재/상위 창 ID를 보내고 있는지 확인하세요.

iframe의 src를 업데이트할 때 해당 오류가 발생합니다.

다음과 같이 기본 창에 있는 요소의 이벤트(내 경우에는 클릭)에 액세스하여 해당 오류가 발생했습니다(기본/가장 바깥쪽 창을 직접 호출).

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은 IE의 HTML을 완전히 재정의합니다. Chrome에서는 동작이 다릅니다.

우리는 그것을 다음과 같이 변경했습니다:

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

따라서 문제를 해결한 스크립트를 유지했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top