Skip to main content

Bug Tracker

Side navigation

#4787 closed bug (fixed)

Opened June 19, 2009 03:59AM UTC

Closed November 11, 2009 06:57PM UTC

Last modified March 15, 2012 07:47PM UTC

$(document).ready() frame detection / cross-domain error in IE6

Reported by: richdougherty Owned by:
Priority: major Milestone: 1.4
Component: event Version: 1.3.2
Keywords: Cc:
Blocked by: Blocking:
Description

I am using JQuery within frames that set document.domain. This is causing problems for me in IE6 but not in FF2.

The frame detection code in JQuery 1.3.2 (used in ready(), added in #3988) seems to cause an 'Access is denied' exception when I subsequently try to access window.frameElement. The problem seems to be the fact that JQuery accesses window.top, which causes some weird time-dependent interaction with window.frameElement.

Here is a two-frame test case that illustrates the problem caused by window.top. The parent frame sets document.domain to localhost and includes a child iframe. The child iframe likewise sets document.domain to localhost and then it tries to access window.frameElement. This access may cause an exception (presumably 'Access is denied'), in which case it tries again in 100ms. It keeps trying until it succeeds, which - strangely enough - seems to happen if it keeps trying for long enough.

With the code shown below, window.frameElement is accessible straight away. But I uncomment window.top or window.parent and try it again then it will takes 9-15 seconds for window.frameElement to become available.

parent.html

<html>
<body>
<h2>Parent</h2>
<script type="text/javascript">
document.domain = 'localhost';
</script>
<iframe src="child.html" height="200" width="200"/>
</body>
</html>

child.html

<html>
<body>
<h2>Child</h2>
<script type="text/javascript">

// If any of the following lines are uncommented, then it
// will take 9-14 seconds for polling to succeed.
//window.top;
//window.parent;

document.domain = 'localhost';

function time() {
    return (new Date()).getTime();
}

var start = time();
var attempts = 0;
function attempt() {
}

function poll() {
    attempts++;
    var result;
    try {
        window.frameElement;
        // Success! Show the time taken.
        alert('attempts: ' + attempts + ', time: ' + (time() - start));
    } catch (e /* Access is denied */ ) {
        // Failure. Try again in 100ms.
        setTimeout(poll, 100);
    }
}

poll();
</script>
</body>
</html>

After finding this out I was able to get JQuery working for me by changing its frame detection code from

// If IE and not an iframe
// continually check to see if the document is ready
if ( document.documentElement.doScroll && window == window.top ) (function(){
    ...

to

// Check if we're in a frame by looking for enclosing element.
var toplevel;
try {
  toplevel = window.frameElement === undefined;
} catch ( error ) {
  // Assume we're in a frame that cannot access its parent frame.
  toplevel = false;
}

// If IE and not an iframe
// continually check to see if the document is ready
if ( document.documentElement.doScroll && toplevel ) (function(){

There's probably a better way to fix this, but I'm including it in case it helps.

More details:

IE 6.0.2900.2180.xpsp_sp2.qfe.090206-1239

Windows XP Pro 5.1.2600 SP2 Build 2600

Attachments (0)
Change History (3)

Changed June 19, 2009 04:11AM UTC by richdougherty comment:1

I should also say, I can reproduce this problem reliably by refreshing the page once it has already been loaded once. It doesn't (usually) occur when I first load the page in a fresh browser.

Changed June 24, 2009 04:43PM UTC by jdalton comment:2

The delay is also gone if you remove setting the document.domain in the parent.html.

I can reproduce your test case. This is a great find. Thanx.

Changed November 11, 2009 06:57PM UTC by john comment:3

component: coreevent
resolution: → fixed
status: newclosed