Bug Tracker

Opened 10 years ago

Closed 9 years ago

Last modified 7 years ago

#4280 closed bug (fixed)

"Permission Denied" errors in IE7 when unloading documents

Reported by: haukurhaf Owned by: brandon
Priority: major Milestone: 1.4
Component: event Version: 1.4a1
Keywords: Access denied unload remove event Cc:
Blocked by: Blocking:

Description

I've got a document with an iframe, which has a load event applied by jquery.

On unload of the parent document, I get an permission denied error message even though the parent and the iframe are on the same domain.

It appears as if the fix to prevent memory leaks in IE is failing.

This is the function where the error originates:

Prevent memory leaks in IE And prevent errors on refresh with events like mouseover in other browsers Window isn't included so as not to unbind existing unload events jQuery( window ).bind( 'unload', function(){

for ( var id in jQuery.cache )

Skip the window if ( id != 1 && jQuery.cache[ id ].handle )

jQuery.event.remove( jQuery.cache[ id ].handle.elem );

});

The error itself is thrown in the jQuery.event.remove method, specifically in this line here:

if ( elem.nodeType == 3
elem.nodeType == 8 )

The "Permission Denied" error occurs when accessing the .nodeType property of the elem object.

This is our lazy fix for this problem:

Detach an event or set of events from an element remove: function(elem, types, handler) {

don't do events on text and comment nodes

try {

if ( elem.nodeType == 3
elem.nodeType == 8 )

return;

} catch(e) {

return;

}

Just enclose this line in a try-catch statement and return false if an error occurs. I don't believe this has any bad side-effects, except perhaps the memory problem with IE.

Change History (13)

comment:1 Changed 10 years ago by dmethvin

Let's first figure out why the problem is happening before trapping and ignoring the error. Can you provide a simple test case that includes the minimal script and HTML to reproduce the problem?

comment:2 Changed 10 years ago by haukurhaf

Hi,

I've been trying to reproduce this bug with as little HTML/Script as possible, but so far I haven't been able to do so. It seems as if the bug is only triggered when certain combination of things are present on the pages.

The project where I'm having this bug is a quite large CMS system and it's kinda difficult for me to gradually include more and more stuff from it until the bug triggers.

Perhaps this ticket should just be ignored until I'm able to reproduce the bug with a more manageble piece of HTML/JS.

comment:3 Changed 10 years ago by daw

I am having the same problem. Also using iframes. They are dynamically created.

The problem seems to occur when having an iframe with a form, and the form is posted to. It does not occur if we just view the page. Only after having posted the form and the iframe has loaded another page, and we then try to close down the main window (or navigate away from it).

A try..catch would solve it.

comment:4 Changed 10 years ago by daw

If someone else is having a problem with this, search in jquery.js for "Prevent memory leaks in IE" and apply a try...catch around the call to jQuery.event.remove():

// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover in other browsers
// Window isn't included so as not to unbind existing unload events
jQuery( window ).bind( 'unload', function(){
	for ( var id in jQuery.cache )
		// Skip the window
		if ( id != 1 && jQuery.cache[ id ].handle ) try {
			jQuery.event.remove( jQuery.cache[ id ].handle.elem );
		} catch (e) {};
});

comment:5 Changed 10 years ago by pbcomm

I had the same issue with one of my scripts and added try, catch is various places mentioned in this post and they all seem to fail. After further investigation I have made the following changes:

Line: 2523 (event.remove)

if ( elem.nodeType == 3
elem.nodeType == 8 )

Corrected to:

if ( typeof elem.nodeType === 'undefined'
elem.nodeType == 3 elem.nodeType == 8 )

This solves the issue. I will post a test case tomorrow.

comment:6 Changed 10 years ago by pbcomm

Please ignore my comments above. This ticket should be closed as this is not a jQuery issue. The issue on IE7 with unload event only exists if the document.domain is being set to invalid or empty value and if there is functionality that uses location object.

comment:7 Changed 10 years ago by wangyun

This is very much a jQuery problem. The application we run contains multiple domain. All of them belong to 'subdomain.domain.com'. So every page has a valid 'document.domain="subdomain.domain.com"' set. When I added the change to jQuery as suggested by <daw>. The error is gone. Hope there is a more elegant way to fix this.

comment:9 Changed 10 years ago by aakoch

I too am seeing this issue and was able to create a simple webpage to demonstrate it: http://adamkoch.com/permission_denied.html

It happens when I remove the iframe and then refresh the page.

I have only seen this issue in IE7 and IE8, not in FF3 nor FF3.5

comment:10 Changed 10 years ago by aakoch

In response to pbcomm, I'm not doing anything to the "document.domain" in my example and am getting this error.

Also, my test page doesn't seem to produce the error every time.

comment:11 Changed 10 years ago by shonny

It can be reproduced in IE6 , IE7, IE8. Open new Tab or window in IE. Enter any address (f.e. http://jquery.com/). Then enter http://www.shonny.mail.ua/. Put the cursor into "Message text:" field. After this You must click IE Back button 2 times.

It is iframe, with document.body.contentEditable=true and document.designMode="on". We have used .bind('mousedown keydown', function (){...}) on this document.

comment:12 Changed 9 years ago by dmethvin

This is a result of a "feature" implemented with IE6 when XP SP2 was released. Any time an iframe is reloaded, any references to objects within it are invalidated by IE and result in "Permission Denied" if you try to use them.

Addressing wangyun's comment, this is *not* a cross-domain issue; IE is shooting all the iframe object references out from under the scripts whenever the iframe is removed or reloaded. See the discussion of Object Caching here: http://msdn.microsoft.com/en-us/library/ms649488%28VS.85%29.aspx

The case shonny mentions with designMode is specifically called out here as a problem: http://technet.microsoft.com/en-us/library/cc781229%28WS.10%29.aspx

I also grabbed this from a private email I got from a Microsoft developer back in 2004 regarding object caching:

Whenever a script changes the content of another window, frame, or element, Internet Explorer now invalidates any objects it contains. If the script attempts to use an invalid object, it will receive a "permission denied" error. The controlling script can obtain a valid reference to the window's new object by retrieving the property again. Instances where scripts would need to re-cache a window object include the use of window.location, document.URL, window.navigate, or document.write.

With all that in mind, maybe the try/catch is the way to fix it. Any references to elements in the old iframe that exist elsewhere will still cause this problem if accessed though.

comment:13 Changed 9 years ago by john

Priority: criticalmajor
Resolution: fixed
Status: newclosed
Version: 1.3.21.4a1

comment:14 Changed 8 years ago by anonymous

There's a problem with the above code when being used with Microsoft's ASP.net framework.

Specifically the ASP.net framework assigns a method to window.nodeName which causes jQuery.acceptData() to fail on line 1230 with an "Object doesn't support this property method"

I've fixed this by manually re-assigning window.nodeName to another variable before I include jQuery and then back once jQuery and the UI are loaded. But this is something that might warrant some kind of fix. It appears this behavior causes both jQuery and the jQuery UI to fail, I'm not sure what the best fix is since that behavior is depended on by an unknown amount of code in both libraries.

Note: See TracTickets for help on using tickets.