it-swarm-vi.tech

Điều gì gây ra lỗi "Không thể thực thi mã từ tập lệnh được giải phóng"

Tôi nghĩ rằng tôi đã tìm thấy giải pháp trước đây (xem blog ) của tôi:

Nếu bạn từng gặp lỗi JavaScript (hoặc phải là JScript) "Không thể thực thi mã từ tập lệnh được giải phóng" - hãy thử di chuyển bất kỳ thẻ meta nào trong đầu để chúng nằm trước thẻ script của bạn. 

... nhưng dựa trên một trong những bình luận blog gần đây nhất, cách khắc phục tôi đề xuất có thể không hiệu quả với tất cả mọi người. Tôi nghĩ rằng đây sẽ là một điều tốt để mở ra cho cộng đồng StackOverflow ....

Điều gì gây ra lỗi "Không thể thực thi mã từ tập lệnh được giải phóng" và các giải pháp/cách giải quyết là gì?

57
Tom Robinson

Có vẻ như bạn đã gặp phải một lỗi/vấn đề theo cách xử lý một số thẻ hoặc bạn có tham chiếu đến các đối tượng được phát hành mà bạn đang cố gắng thực hiện các phương thức.

Trước tiên tôi sẽ di chuyển bất kỳ thẻ <meta> nào trước bất kỳ thẻ <script> nào như được đề xuất tại đây và nhiều nơi khác.

Sau đó kiểm tra xem bạn có vấn đề về trang/bảo mật được thảo luận tại đây .

19
Joe Skora

Bạn gặp lỗi này khi bạn gọi một hàm được tạo trong cửa sổ hoặc khung không còn tồn tại. 

Nếu bạn không biết trước nếu cửa sổ vẫn còn tồn tại, bạn có thể thử/bắt để phát hiện nó:

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

Lỗi xảy ra khi cửa sổ 'cha mẹ' của tập lệnh bị loại bỏ (nghĩa là: đã đóng) nhưng tham chiếu đến tập lệnh vẫn được giữ (chẳng hạn như trong cửa sổ khác) được gọi. Mặc dù 'đối tượng' vẫn còn sống, bối cảnh mà nó muốn thực thi là không.

Nó hơi bẩn, nhưng nó hoạt động cho Tiện ích thanh bên Windows của tôi:

Đây là ý tưởng chung: Cửa sổ 'chính' thiết lập một hàm sẽ đánh giá một số mã, yup, nó thật xấu xí . Sau đó, một 'đứa trẻ' có thể gọi đây là "hàm xây dựng" (đó là/bị ràng buộc với phạm vi của cửa sổ chính /) và lấy lại một chức năng cũng bị ràng buộc với cửa sổ 'chính'. Tất nhiên, một nhược điểm rõ ràng là chức năng 'bật lại' không thể đóng trên phạm vi mà nó dường như được xác định trong ... dù sao, cũng đủ để nói lung tung:

Đây là mã giả một phần, nhưng tôi sử dụng một biến thể của nó trên Tiện ích thanh bên Windows (Tôi cứ nói điều này vì Tiện ích thanh bên chạy trong "vùng không giới hạn 0", có thể - hoặc không - thay đổi kịch bản rất nhiều.)


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

Là một biến thể, cửa sổ chính sẽ có thể truyền hàm functionBuilder cho cửa sổ con - miễn là hàm functionBuilder được xác định trong ngữ cảnh cửa sổ chính!

Tôi cảm thấy như tôi đã sử dụng quá nhiều từ. YMMV.

18
user166390

Nếu bạn đang cố gắng truy cập đối tượng JS, cách dễ nhất là tạo một bản sao:

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

Hy vọng nó sẽ giúp.

8
Grzegorz Ciwoniuk

Đây là một trường hợp rất cụ thể trong đó tôi đã thấy hành vi này. Nó có thể tái tạo cho tôi trong IE6 và IE7.

Từ trong iframe:

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

Sau đó, sau khi tải lại iframe với nội dung mới, trong cửa sổ chứa iframe:

window.mySpecialHandler();

Cuộc gọi này không thành công với "Không thể thực thi mã từ tập lệnh được giải phóng" vì myecialHandler được xác định trong ngữ cảnh (DOM gốc của iframe) không còn tồn tại. (Tải lại iframe đã phá hủy bối cảnh này.)

Tuy nhiên, bạn có thể đặt các giá trị "tuần tự hóa" một cách an toàn (nguyên thủy, biểu đồ đối tượng không trực tiếp tham chiếu các hàm) trong cửa sổ cha. Nếu bạn thực sự cần một cửa sổ riêng (trong trường hợp của tôi, iframe) để chỉ định một số công việc cho một cửa sổ từ xa, bạn có thể chuyển công việc dưới dạng Chuỗi và "đánh giá" nó trong máy thu. Hãy cẩn thận với điều này, nó thường không làm cho việc thực hiện sạch sẽ hoặc an toàn.

6
aaron

Bắt đầu từ IE9, chúng tôi bắt đầu nhận được lỗi này khi gọi .getTime () trên một đối tượng Ngày được lưu trữ trong một mảng trong một Đối tượng khác. Giải pháp là đảm bảo đó là Ngày trước khi gọi các phương thức Ngày:

Thất bại: rowTime = wl.rowData[a][12].getTime()

Đạt: rowTime = new Date(wl.rowData[a][12]).getTime()

5
Tom

Lỗi này có thể xảy ra trong MSIE khi cửa sổ con cố gắng giao tiếp với cửa sổ cha không còn mở.

(Không chính xác văn bản thông báo lỗi hữu ích nhất trên thế giới.)

3
pcorcoran

Tôi gặp phải vấn đề này khi bên trong khung con tôi đã thêm một loại tham chiếu vào cửa sổ cấp cao nhất và cố gắng truy cập nó sau khi cửa sổ con được tải lại

i E.

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

Tôi đã có thể giải quyết vấn đề bằng cách chỉ sử dụng các loại nguyên thủy

// set the value on first load
window.top.timestamp = Number(new Date());
2
wycleffsean

Đây thực sự không phải là một câu trả lời, nhưng nhiều hơn một ví dụ về nơi điều này chính xác xảy ra.

Chúng tôi có khung A và khung B (đây không phải là ý tưởng của tôi, nhưng tôi phải sống với nó). Khung A không bao giờ thay đổi, Khung B thay đổi liên tục. Chúng tôi không thể áp dụng thay đổi mã trực tiếp vào khung A, vì vậy (theo hướng dẫn của nhà cung cấp), chúng tôi chỉ có thể chạy JavaScript trong khung B - khung chính xác luôn thay đổi.

Chúng tôi có một đoạn JavaScript cần chạy cứ sau 5 giây, do đó, JavaScript trong khung B tạo ra một thẻ script mới và chèn vào phần đầu của khung B. SetInterval tồn tại trong tập lệnh mới này (đoạn được chèn), như cũng như các chức năng để gọi. Mặc dù JavaScript được chèn được tải kỹ thuật bởi khung A (vì hiện tại nó chứa thẻ script), một khi khung B thay đổi, hàm setInterval không thể truy cập được nữa.

1
Nathan Crause

Tôi đã gặp lỗi này trong IE9 trong một trang cuối cùng mở iFrame. Miễn là iFrame chưa mở, tôi có thể sử dụng localStorage. Khi iFrame được mở và đóng, tôi không thể sử dụng localStorage nữa vì lỗi này. Để khắc phục, tôi đã phải thêm mã này vào Javascript nằm trong iFrame và cũng sử dụng localStorage.

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

Khi cập nhật src của iframe tôi gặp lỗi đó.

Có lỗi đó bằng cách truy cập một sự kiện (nhấp vào trường hợp của tôi) của một phần tử trong cửa sổ chính như thế này (gọi trực tiếp cửa sổ chính/ngoài cùng): 

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

Tôi chỉ thay đổi nó như thế này và nó hoạt động tốt (gọi cha mẹ của cha mẹ của cửa sổ iframe):

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

Khung nội tuyến của tôi chứa phương thức cũng nằm trong khung nội tuyến khác.

0
Chan

Các giải thích rất phù hợp trong các câu trả lời trước. Chỉ cần cố gắng để cung cấp kịch bản của tôi. Hy vọng điều này có thể giúp đỡ người khác.

chúng tôi đã sử dụng:

<script> window.document.writeln(table) </script>

và gọi các chức năng khác trong tập lệnh trên các sự kiện onchange nhưng ghi lại hoàn toàn ghi đè HTML trong IE khi nó có hành vi khác nhau trong chrome.

chúng tôi đã thay đổi nó thành:

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

Do đó giữ lại các kịch bản đã khắc phục vấn đề.

0
pavan kumar

gặp lỗi này trong DHTMLX trong khi mở id hội thoại & id cha hoặc id cửa sổ hiện tại không tìm thấy 

        $(document).ready(function () {

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

});

Chỉ cần đảm bảo rằng bạn đang gửi id cửa sổ hiện tại/chính xác trong khi mở một cuộc hội thoại

0
panky sharma