iframe contentWindow throws Access Denied error after shortening document.domain

47,084

Solution 1

First take a look at the correct answer from this post. It looks to me like that could be your issue.

If not that then maybe this quick hack I saw from another post might help.

 var frame = $('<iframe>')
.attr('id', 'myIframe')
.addClass('someClass')
.attr('src', 'javascript:(function () {' +'document.open();document.domain=\'myDomain.net\';document.close();' + '})();');
.appendTo($('#someDiv'));

Not sure if this is relevant but I also found this on the web link.

OK, so to respond to your comment. The javascript function isn't assigning the source, it's setting the document domain which apparently doesn't get done correctly in I.E.

Check out this link for another example and explanation.

So what I would try might be something like this ...

var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';    
wrapUpIframe.src = setSrc();
document.body.appendChild(wrapUpIframe);

function setSrc(){document.open();document.domain=\'dc.com\';document.close();return 'WrapUpDialog.html';}

You might have to play around with how to return the actual url for the iframe after running the function that sets the document domain. But from what I am seeing this might work for you.

I had a similar issue but not exactly the same problem which is why I can't give you an exact fix. The function setting the document domain was what got me past the access denied error.

You could also add this to your main document to really make sure the domains match.

 <script type="text/javascript">
    document.domain = 'dc.com';
  </script>

I also wanted to add a link for some explanation on explicitly setting the document.domain that I had used before. This was helpful to me in the past. Particularly this quote ...

Explicitly setting the value indicates intent to "cooperate" with a script on another subdomain (under the same parent domain).

Dor, you may be having a timing issue. I found some code (here) that I just tested that works for me. It makes sure that the iframe is loaded before you try to access the contentWindow.

var iframe = document.createElement("iframe");
iframe.src = "WrapUpDialog.html";

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
        alert("Local iframe is now loaded.");
    });
} else {
    iframe.onload = function(){
        alert("Local iframe is now loaded.");
    };
}

document.body.appendChild(iframe);

var iframeWindow = iframe.contentWindow || iframe.contentDocument.parentWindow;

Solution 2

How do you serve your files? Do you see file:/// in your address bar? If so, try serving your code using a webserver.

Google Chrome gives an access denied error if I try your code using file:///, but it works when served from a local webserver (i.e. the address starts with http://localhost/).

Solution 3

Since you have not yet accepted any of the answers given you probably still have the problem.

Try setting document.domain explicitly in both HTML pages (you seem to be doing this in one page only). This means that as @Vic suggested, you need to add the following javascript code to the HTML that includes the iframe:

document.domain = 'dc.com';

This means that your code would look like this:

document.domain = 'dc.com';
var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

Then, in WrapUpDialog.html itself (not in the main page because then you would circumvent the security system!) you need to set document.domain as well:

document.domain = dc.com;

So this line of yours will NOT work:

WrapUpDialog3.document.domain = 'dc.com';

because WrapUpDialog.html itself needs to grant permission to its "parent" page to execute its javascript.

There is more info on this page: What does document.domain = document.domain do?.

Final hint: do try your code using different browsers: IE9, Firefox, Google Chrome. This can help you identify whether you are perhaps dealing with a quirk of one particular browser.

Share:
47,084
Dor Cohen
Author by

Dor Cohen

C# and web developer

Updated on July 18, 2022

Comments

  • Dor Cohen
    Dor Cohen almost 2 years

    I create an IFRAME dynamically in the following way:

    var wrapUpIframe = document.createElement("iframe");
    wrapUpIframe.id = 'WrapUpDialog3';
    wrapUpIframe.src = 'WrapUpDialog.html';    
    document.body.appendChild(wrapUpIframe);
    

    after the dynamic creation my document.domain is being shortened from Servername.dc.com to only dc.com,

    but when I try to access contentWindow I got an Access is denied error:

    document.getElementById("WrapUpDialog3").contentWindow.SomeFunction();
    

    Note: When I define the IFRAME statically in the HTML it works fine.
    I also tried to change my IFRAME document.domain in the following way:

    WrapUpDialog3.document.domain = dc.com;
    

    I checked both document.domain and my IFRAME domain and they are both identical.

    What can I do?

    I'm working with IE9.

  • Dor Cohen
    Dor Cohen about 11 years
    Thanks for the reply, my src should be an external html page - WrapUpDialog.html, how can load it using your suggestion?
  • Dor Cohen
    Dor Cohen about 11 years
    I am using regular HTML page, no files
  • Vic
    Vic about 11 years
    Dor, are you trying to load the js functions you mentioned in this question (stackoverflow.com/questions/14849606/…) in this html page?
  • Vic
    Vic about 11 years
    Shame I didn't get the bounty. :)
  • Vic
    Vic almost 11 years
    Dor, if it was the timing issue that was the problem let me know. I'll edit my answer so that others know as well.